遍历二叉树:前序、中续、后续、递归、非递归
树节点定义:
struct Node { int data; Node *left; Node *right; };
递归实现:
void visit(Node *node) { assert(node != NULL); printf("%d ", node->data); } void visitPrevOrderRec(Node *tree) { if (tree == NULL) return ; visit(tree); visitPrevOrderRec(tree->left); visitPrevOrderRec(tree->right); } void visitMidOrderRec(Node *tree) { if (tree == NULL) return ; visitMidOrderRec(tree->left); visit(tree); visitMidOrderRec(tree->right); } void visitPostOrderRec(Node *tree) { if (tree == NULL) return ; visitPostOrderRec(tree->left); visitPostOrderRec(tree->right); visit(tree); }
简单直接的非递归实现:
enum _travel_type{ VISIT, TRAVEL, }; typedef pair<enum _travel_type, Node *> NodeTravel; void visitPrevOrderSimple(Node *tree) { stack<Node *> stack; if (tree == NULL) return ; stack.push(tree); while (!stack.empty()) { Node *cur = stack.top(); stack.pop(); visit(cur); if (cur->right != NULL) stack.push(cur->right); if (cur->left != NULL) stack.push(cur->left); } } void visitMidOrderSimple(Node *tree) { stack<NodeTravel> stack; if (tree == NULL) return ; stack.push(NodeTravel(TRAVEL, tree)); while (!stack.empty()){ NodeTravel t = stack.top(); stack.pop(); Node *cur = t.second; if (t.first == VISIT) { visit(cur); } else { if (cur->right) stack.push(NodeTravel(TRAVEL, cur->right)); stack.push(NodeTravel(VISIT, cur)); if (cur->left) stack.push(NodeTravel(TRAVEL, cur->left)); } } } void visitPostOrderSimple(Node *tree) { stack<NodeTravel> stack; if (tree == NULL) return ; stack.push(NodeTravel(TRAVEL, tree)); while (!stack.empty()) { NodeTravel t = stack.top(); stack.pop(); Node *cur = t.second; if (t.first == VISIT) { visit(cur); } else { stack.push(NodeTravel(VISIT, cur)); if (cur->right != NULL) stack.push(NodeTravel(TRAVEL, cur->right)); if (cur->left != NULL) stack.push(NodeTravel(TRAVEL, cur->left)); } } }
对于中续和后续遍历,还有更好的方法(不需要借助pair):
void visitMidOrder(Node *tree) { stack<Node *> stack; while (tree != NULL || !stack.empty()) { while (tree != NULL) { stack.push(tree); tree = tree->left; } if (!stack.empty()) { Node *n = stack.top(); stack.pop(); visit(n); tree = n->right; } } } void visitPostOrder(Node *tree) { stack<Node *> stack; if (tree == NULL) return ; stack.push(tree); Node *pp = NULL; while (!stack.empty()) { Node *cur = stack.top(); Node *last = cur->right; if (last == NULL) last = cur->left; if (last == NULL || last == pp) { visit(cur); pp = cur; stack.pop(); } // last != NULL && last != pp else if (cur->left == NULL || cur->left == pp) { stack.push(cur->right); } else { stack.push(cur->left); } } }
发现任何错误或者有更好的方法,欢迎回复!