二叉树的递归和非递归遍历
1.递归遍历:
struct node { int value; node* left; node* right; }; void preOrder(node* root) { if(root == NULL) return; visit(root); preOrder(root->left); preOrder(root->right); }
2.非递归遍历:
先序:
void preOrderNonrecursive(node* root) { stack<node* > s; s.push(root); while(!s.empty()) { node* pnode = s.pop(); visit(pnode); if(pnode->right) s.push(pnode.right); if(pnode->left) s.push(pnode.left); } }
中序:
void inOrderNonrecursive(node* root) { stack<node*> s; s.push(root); node* current = root; while(!s.empty() || current != NULL) { if(current != NULL) { s.push(current); current = current->left; } else { current = s.pop(); s.visit(current); current = current->right; } } }
后序:
后序的非递归实现最为复杂,这里有一个巧妙的方法:
后序的遍历原则为,左子树,右子树,根。可见根是最先遍历到,最后访问的元素。正好符合栈的特点。
所以方法是,遍历树的同时,将根节点压入栈,最后全部出栈,就是后序的遍历序列了。
void postOrderNonrecursive(node* root) { stack<node*> sTraverse, sVisit; sTraverse.push(root); while(!sTraverse.empty()) { node* pnode = sTraverse.pop(); if(pnode->left) sTraverse.push(pnode->left); if(pnode->right) sTraverse.push(pnode->right); sVisit.push(pnode); } while(!sVisit.empty()) sVisit.pop(); }
这里要注意进栈和出栈的顺序。对于sTraverse栈,进栈的顺序为根,左右,出栈顺序为根,右左,正好对应sVisit栈的进栈顺序,故sVisit的出栈顺序为左,右,根,正好为后序遍历的顺序。