二叉树前序,中序,后序遍历大全
二叉树是数据结构的基础,递归的版本是十分简单而且简洁,但是非递归版本就相对比较复杂些。
1.前序非递归便利二叉树:
前序比较简单,从根开始访问,并一直往左,同时将访问后节点的右子树入栈(如果存在的话),直到栈空。
void preorder(TreeNode* root) { stack<TreeNode*> st; if (root == NULL) return ; st.push(root); while (!st.empty()) { TreeNode* p = st.top(); st.pop(); while (p != NULL) { cout << p->value << endl; if (p->r != NULL) st.push(p->r); p = p->l; } } }
2.中序非递归遍历二叉树:
中序遍历即,不断往左走,同时入栈所有经过的元素,找到最左边的节点访问,然后将访问后节点的右子树,入栈。此处有一个小窍门,如果右子树不存在,实际上我们应该访问根,所以我们应该压入NULL,压入NULL的目的在于阻止遍历过程再往左走。
void inorder(TreeNode* root) { stack<TreeNode*> st; if (root == NULL) return ; st.push(root); while (!st.empty()) { while (st.top() != NULL) st.push(st.top()->l); st.pop(); if (!st.empty()) { TreeNode* x = st.top(); cout << x->value << endl; st.pop(); //if (x->r != NULL) st.push(x->r); } } }
3.二叉树后序遍历非递归:
后序比较复杂,很多书上面都没有列出来。后序便利需要用另外一个栈来保存当前节点的右子树是否已经访问。
void posttravel(TreeNode* root) { stack<TreeNode*> st; stack<bool> right; if (root == NULL) return; st.push(root); right.push(false); while (!st.empty()) { while (st.top() != NULL) { st.push(st.top()->l); right.push(false); } st.pop(); right.pop(); if (st.empty()) break; if (right.top() == false) { right.pop(); right.push(true); st.push(st.top()->r); right.push(false); } else { TreeNode* x = st.top(); cout <<x->value << endl;; st.pop(); right.pop(); right.push(false); st.push(NULL); } } }
注意代码中故意压栈的NULL,它的作用在于阻止继续往左遍历,