データ構造とアルゴリズム インタビューの質問: バイナリ ツリーをミラー イメージに変換する関数を実装します。(再帰的または非再帰的実装)
はじめに: バイナリ ツリーをミラー イメージに変換する関数を実装します。(再帰的または非再帰的実装)
アルゴリズムの実装アイデアは次のとおりです。
- 現在のノードの左右のサブツリーを交換します。
- このノードの左右のサブツリーを再帰的にミラーリングします。
以下は、C++ を使用してバイナリ ツリーをミラー イメージ (非再帰実装) に変換するコードと詳細なコメントです。
#include <iostream>
#include <stack>
using namespace std;
// 定义二叉树结构
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {
}
};
// 将一棵二叉树转换为它的镜像(非递归实现)
void mirror_iterative(TreeNode* root) {
if (root == nullptr) return;
stack<TreeNode*> s{
{
root}};
while (!s.empty()) {
TreeNode* node = s.top();
s.pop();
swap(node->left, node->right); // 交换左右子树
if (node->left != nullptr) s.push(node->left);
if (node->right != nullptr) s.push(node->right);
}
}
int main() {
// 构造一棵二叉树
TreeNode* root = new TreeNode(4);
root->left = new TreeNode(2);
root->right = new TreeNode(7);
root->left->left = new TreeNode(1);
root->left->right = new TreeNode(3);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(9);
// 转换并输出镜像结果
mirror_iterative(root);
cout << root->val << endl; // 4
cout << root->left->val << " "; // 7
cout << root->left->left->val << " "; // 9
cout << root->left->right->val << " "; // 6
cout << root->right->val << " "; // 2
cout << root->right->left->val << " "; // 3
cout << root->right->right->val << endl;// 1
return 0;
}
以下は、同じ関数の再帰実装コードと詳細なコメントです。
#include <iostream>
using namespace std;
// 定义二叉树结构
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {
}
};
// 将一棵二叉树转换为它的镜像(递归实现)
void mirror_recursive(TreeNode* root) {
if (root == nullptr) return;
swap(root->left, root->right); // 交换当前节点的左右子树
// 递归对左右子树进行镜像操作
mirror_recursive(root->left);
mirror_recursive(root->right);
}
int main() {
// 构造一棵二叉树
TreeNode* root = new TreeNode(4);
root->left = new TreeNode(2);
root->right = new TreeNode(7);
root->left->left = new TreeNode(1);
root->left->right = new TreeNode(3);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(9);
// 转换并输出镜像结果
mirror_recursive(root);
cout << root->val << endl; // 4
cout << root->left->val << " "; // 7
cout << root->left->left->val << " "; // 9
cout << root->left->right->val << " "; // 6
cout << root->right->val << " "; // 2
cout << root->right->left->val << " "; // 3
cout << root->right->right->val << endl;// 1
return 0;
}
どちらのコードも、バイナリ ツリーの構造を定義する方法でバイナリ ツリーを構築します。mirror_iterative()
この関数は非再帰実装にスタックを使用するため、関数呼び出しのスタックの深さを回避し、スペースの複雑さを軽減します。mirror_recursive()
関数は再帰を使用して実装されているため、コードはより簡潔で理解しやすくなります。2 つの関数の考え方は次のとおりです。ノードでは、左右のサブツリーを交換した後、その左右のサブツリーに対して同じ操作を再帰的に実行します。