二叉树の探索方法には、主に以下の3つの方式があります:
- 先順序探索
- 中順序探索
- 後順序探索
以下に、それぞれの探索方法の実装例を示します:
再帰的探索
class Solution {
public:
vector<int> result;
void preorder(BinaryTreeNode<int>* node) {
if (node == nullptr) return;
result.push_back(node->value);
preorder(node->left);
preorder(node->right);
}
void inorder(BinaryTreeNode<int>* node) {
if (node == nullptr) return;
inorder(node->left);
result.push_back(node->value);
inorder(node->right);
}
void postorder(BinaryTreeNode<int>* node) {
if (node == nullptr) return;
postorder(node->left);
postorder(node->right);
result.push_back(node->value);
}
vector<int> getPreorderTraversal(BinaryTreeNode<int>* root) {
preorder(root);
return result;
}
};
非再帰的探索
class Solution {
public:
vector<int> result;
void preorderIterative(BinaryTreeNode<int>* root) {
if (root == nullptr) return;
stack<BinaryTreeNode<int>*> stack;
stack.push(root);
while (!stack.empty()) {
BinaryTreeNode<int>* current = stack.top();
stack.pop();
result.push_back(current->value);
if (current->right != nullptr) {
stack.push(current->right);
}
if (current->left != nullptr) {
stack.push(current->left);
}
}
}
vector<int> getInorderTraversal(BinaryTreeNode<int>* root) {
if (root == nullptr) return result;
stack<BinaryTreeNode<int>*> stack;
BinaryTreeNode<int>* current = root;
while (current != nullptr || !stack.empty()) {
if (current != nullptr) {
stack.push(current);
current = current->left;
} else {
current = stack.top();
stack.pop();
result.push_back(current->value);
current = current->right;
}
}
return result;
}
};
多様な探索方法
二叉树の探索方法は、応用によってさまざまに変化します:
- 層序探索
- 逆層序探索
- 右側ビュー
- 層ごとの平均値
- 多叉树の層序探索
- 完全二叉树の連結
例:
class Solution {
public:
vector<vector<int>> levelOrderTraversal(BinaryTreeNode<int>* root) {
vector<vector<int>> layers;
if (root == nullptr) return layers;
queue<BinaryTreeNode<int>*> queue;
queue.push(root);
while (!queue.empty()) {
int levelSize = queue.size();
vector<int> currentLevel;
for (int i = 0; i < levelSize; i++) {
BinaryTreeNode<int>* node = queue.front();
queue.pop();
currentLevel.push_back(node->value);
if (node->left != nullptr) {
queue.push(node->left);
}
if (node->right != nullptr) {
queue.push(node->right);
}
}
layers.push_back(currentLevel);
}
return layers;
}
};
class Solution {
public:
vector<vector<int>> reverseLevelOrderTraversal(BinaryTreeNode<int>* root) {
vector<vector<int>> layers;
if (root == nullptr) return layers;
queue<BinaryTreeNode<int>*> queue;
stack<vector<int>> stack;
queue.push(root);
while (!queue.empty()) {
int levelSize = queue.size();
vector<int> currentLevel;
for (int i = 0; i < levelSize; i++) {
BinaryTreeNode<int>* node = queue.front();
queue.pop();
currentLevel.push_back(node->value);
if (node->left != nullptr) {
queue.push(node->left);
}
if (node->right != nullptr) {
queue.push(node->right);
}
}
stack.push(currentLevel);
}
while (!stack.empty()) {
layers.push_back(stack.top());
stack.pop();
}
return layers;
}
};
高度計算
二叉树の深さを計算するアルゴリズム:
class Solution {
public:
int calculateDepth(BinaryTreeNode<int>* root) {
if (root == nullptr) return 0;
return max(calculateDepth(root->left), calculateDepth(root->right)) + 1;
}
};
最小深度を計算するアルゴリズム:
class Solution {
public:
int calculateMinDepth(BinaryTreeNode<int>* root) {
if (root == nullptr) return 0;
if (root->left == nullptr && root->right == nullptr) {
return 1;
}
int leftDepth = root->left != nullptr ? calculateMinDepth(root->left) : INT_MAX;
int rightDepth = root->right != nullptr ? calculateMinDepth(root->right) : INT_MAX;
return min(leftDepth, rightDepth) + 1;
}
};