循环遍历二叉树
循环遍历二叉树
前序遍历
最简单的一种,无脑入栈就行了。
static void preorderTraversal(const Node root, std::ostream &os) {
std::vector<Node> stack;
stack.push_back(root);
while(!stack.empty()) {
auto node = stack.back();
stack.pop_back();
os << node->val << std::endl;
if(node->right) stack.push_back(node->right);
if(node->left) stack.push_back(node->left);
}
}
中序遍历
先处理完左子树,再处理右子树。
static void inorderTraversal(const Node root, std::ostream &os) {
std::vector<Node> stack;
auto node = root;
while(node || !stack.empty()) {
while(node) {
stack.push_back(node);
node = node->left;
}
node = stack.back();
stack.pop_back();
os << node->val << std::endl;
node = node->right;
}
}
后序遍历
需要分情况讨论,看是从父亲到儿子,还是从儿子到父亲。
static void postorderTraversal(const Node root, std::ostream &os) {
std::vector<Node> stack;
stack.push_back(root);
Node prev = nullptr;
while(!stack.empty()) {
auto node = stack.back();
if(!prev || prev->left == node || prev->right == node) {
if(node->left) stack.push_back(node->left);
else if(node->right) stack.push_back(node->right);
} else if(node->left == prev) {
if(node->right) stack.push_back(node->right);
} else {
os << node->val << std::endl;
stack.pop_back();
}
prev = node;
}
}
检查结果
我们可以写一个随机生成树形结构+检验两种遍历结果的函数,检查我们的循环遍历结果是否正确。
树形结构生成:
std::shared_ptr<TreeNode> createRandomTree(int depth, int probability, std::mt19937& gen, std::uniform_int_distribution<int>& dis) {
if (depth <= 0 || dis(gen) > probability) {
return nullptr;
}
auto root = std::make_shared<TreeNode>(dis(gen));
root->left = createRandomTree(depth - 1, probability - 5, gen, dis);
root->right = createRandomTree(depth - 1, probability - 5, gen, dis);
return root;
}
结果检验:
bool compareResults(Node root) {
std::stringstream ss1, ss2;
RecursiveTraversal::preorderTraversal(root, ss1);
IterativeTraversal::preorderTraversal(root, ss2);
if(ss1.str() != ss2.str()) {
std::cerr << "preorderTraversal failed" << std::endl;
return false;
}
else {
std::cout << "preorderTraversal passed" << std::endl;
}
ss1.str(""); ss2.str("");
RecursiveTraversal::inorderTraversal(root, ss1);
IterativeTraversal::inorderTraversal(root, ss2);
if(ss1.str() != ss2.str()) {
std::cerr << "inorderTraversal failed" << std::endl;
return false;
}
else {
std::cout << "inorderTraversal passed" << std::endl;
}
ss1.str(""); ss2.str("");
RecursiveTraversal::postorderTraversal(root, ss1);
IterativeTraversal::postorderTraversal(root, ss2);
if(ss1.str() != ss2.str()) {
std::cerr << "postorderTraversal failed" << std::endl;
return false;
}
else {
std::cout << "postorderTraversal passed" << std::endl;
}
return true;
}