二叉树的遍历是二叉树中最最基础的部分。
这里整理二叉树不用递归实现三种顺序遍历的方式。
不用递归的话,一般需要栈来完成。当然线索二叉树(不需要栈或递归)也可以完成中序遍历,这里着重讨论使用栈的实现方式。
中序遍历
(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;
本文介绍二叉树的非递归遍历方法,包括中序和后序遍历的具体实现。通过栈结构实现了中序遍历的两种方法,并提供了后序遍历的一栈和两栈实现方案。
4845

被折叠的 条评论
为什么被折叠?



