二叉树遍历(迭代版)

首先对于二叉树的先序遍历
我们先对他的访问顺序进行探讨 遍历顺序为 V|L|R 所以可以 直接采用递归版

pre(Tree &root){
visit(root)
pre(root->left)
pre(root->right)
}

仔细观察其规律不难发现 其类似于栈结构的操作(毕竟递归的另一个层面也是用栈实现的)

stack s;
pre (Tree &root){
if(root)
s.push(root);
while(s!empty()){
Tree tem =s.top();
visit(tem);
s.pop();
if(tem->right!=null)s.push(tem->right);
if(tem->left!=null)s.push(tem->left);
}
}

仔细体会代码中的入栈顺序~不难发现 每次弹出栈的顶点都会被访问~ 而根据入栈顺序~不难发现恰好符合先序遍历顺序~
然后我们来感受一下中序遍历~
中序遍历 遍历顺序为L|V|R
首先来看递归版


in(tree& root){
in(root->left);
visit(root);
in(root->right);
}

其顺序不难理解 :先递归到 左边的最底层~ 然后再以L|V|R的方式访问 ,但是这里的访问可能不是很好理解~不妨画一个图~ 所以这返回成迭代版中序遍历的代码为

goleftBranch(Tree* x,stack s ){while(x){s.push(x);x=x->left;}}
stack s;
in(Tree &root){
while(true){
goleftBranch(root,s);
if(s.empty())break;
tem=s.pop();//虽然这里一般分两步 top 和pop分开1
visit(tem->data);
if(hasRightChild(tem))root=tem->right;
}
}

而二叉树后序遍历 其顺序 L|R|V
递归版本代码

post(Tree x){
post(x->left);
post(x->right);
visit(x);
}

关于其迭代版实现由于其访问顺序的特殊性~
所以while 循环因类似于中序而并非前序;

所以中序中的goleft操作也可以使用

post(Tree * x){
stack s;
while (true){
goleftBranch(x,s);
tem=s.pop();
visit(x->data);if(hasrightchild(tem.parent))x=tem.parent.right;
}
}

其实也可以写一个是否有右兄弟节点来简化一下 发挥发挥面向对象思想~
还有一个遍历就是对于二叉树的层次遍历~ 自顶而下~自左往右~
仔细观察层次遍历的思想不难发现~ 这更类似于另一个与栈对立的数据结构 -队列
用队列则可以很easy的实现二叉树的层次遍历~伪代码如下

level(Tree * x){
queue q;
q.enqueue(x);
whlie(!q.empty()){
x = q.top();
visit(x);
q.dequeue();
if(x.hasleft-child)q.enqueue(x->left);
if(x,hasright-child)q.enqueue(x->right);
}
}

你可能感兴趣的:(c++)