二叉树系列 - 二叉树的前/中/后序遍历(非递归)
二叉树的遍历是二叉树中最最基础的部分。
这里整理二叉树不用递归实现三种顺序遍历的方式。
不用递归的话,一般需要栈来完成。当然线索二叉树(不需要栈或递归)也可以完成中序遍历,这种方式在这篇文章中已经讨论过。这里着重讨论使用栈的实现方式。
中序遍历
(1) 双while,第二个内层while是为了不断压入left child。
vector<int> inorderTraversal(TreeNode *root) { vector<int> v; if(!root) return v; TreeNode* tmp = root; stack<TreeNode* > st; while(tmp || !st.empty()){ while(tmp){ st.push(tmp); tmp = tmp -> left; } if(!st.empty()){ tmp = st.top(); st.pop(); v.push_back(tmp -> val); tmp = tmp -> right; } } return v; }
Leet Code: Binary Tree Inorder Traversal AC 8ms
更简单的去掉内层循环的写法,原理其实一样,唯一不同的就是高亮部分。
vector<int> inorderTraversal(TreeNode *root) { vector<int> v; if(!root) return v; TreeNode* tmp = root; stack<TreeNode* > st; while(tmp || !st.empty()){ if(tmp){ st.push(tmp); tmp = tmp -> left; }else{ tmp = st.top(); st.pop(); v.push_back(tmp -> val); tmp = tmp -> right; } } return v; }
Leet Code: Binary Tree Inorder Traversal AC 32ms
后序遍历
(1) 两栈实现法,一个栈st1用类似前序遍历的方式(细微的不同之处在于 left child先进栈),将所有输出存入另一个栈st2中。最后将st2的内容挨个输出就结了。
这种方式非常好理解,因为后序遍历就是那个改动后的前序遍历的倒序输出。st2的作用只有一个:就是逆序。因此如果输出结果是存在vector里的话,把结果直接reverse也可以。
(2) 一栈实现法,这种方式需要定义一个pre指针。
这种方式也很好理解,后序就是parent比孩子后输出,那么我们只要读到parent的时候,不忙着输出parent的值,而是让其留在栈内,把左右孩子继续往栈里压。
那啥时候才能输出parent呢?当发现左右孩子已经被输出的时候,就可以输出parent 了。pre就是用来记录最近输出的结点的。
vector<int> postorderTraversal(TreeNode *root) { std::vector<int> v; if(NULL == root) return v; std::stack<TreeNode*> st; TreeNode* pre = NULL; TreeNode* cur = NULL; st.push(root); while(!st.empty()){ cur = st.top(); if((NULL == cur -> right && NULL == cur -> left) || (NULL != pre && (pre == cur -> right || pre == cur -> left))){ //For each node, there will never be such case that one child is pre, one child is not yet traversed. Because both children are printed (or it's NULL) before stack.top == cur. //So if one child points to pre, that means current node can also be printed. //NULL != pre is used for the edge case that only two nodes: root contains one left node. st.pop(); v.push_back(cur -> val); pre = cur; }else{ if(NULL != cur -> right) st.push(cur -> right); if(NULL != cur -> left) st.push(cur -> left); } } return v;
------------------------------------------------
Felix原创,转载请注明出处,感谢博客园!
posted on 2014-12-08 01:03 Felix Fang 阅读(1102) 评论(0) 编辑 收藏 举报