相信大家用两个栈(两个栈可以实现一个队列的效果)来实现二叉树的螺旋遍历是一件比较容易(写起来也不是十分轻松)的活吧,但是如果用一个栈就能实现这个问题的话,看来我们得花点心思了!!(嘻嘻)
那么什么是螺旋遍历呢?
---------------1-----------------
--------3-----------2---------------
---4------5-----6-------7
-----------------------------8
螺旋遍历的结果是:12345678
我们要借助前两章讲解的一些基础知识混合在一起我们才能解决这个问题,以下是我们从前几篇的博客中得到的基本信息,希望大家理解
1.二叉树基本三种遍历(前序中序后序)都可以用一个栈来实现非递归遍历(这篇博客小生写过哦,如果不懂可以看看的)
2.不管三种遍历的哪种遍历,对于同层元素都是左边元素右边元素的前面(前序:中左右,中序:左中右,后序:左右中)
3.树的高度可以辨识中一颗树种哪些元素是在同一层的(关于树中任意元素的高度求法可以参见我的博客)
通过以上三点我们就可以实现对二叉树的螺旋遍历的吗?(基本上可以吧,但是需要进行两项改造)
首先获取树节点的高度
int get_depth(BinaryTreeNode *r)
{
int depth=0;
if(r)
{
int a=get_depth(r->m_pleft);
int b=get_depth(r->m_pright);
depth=(a>b)?a:b;
depth++;
}
return depth;
}
其实我们在构建二叉树的属性时候就可以把高度这个值付给二叉树作为树的基本属性,这样我们建树的时候就就可以赋值高度这个值(关键在于你的爱好)
我们再改写一下树的先序遍历让它只打印同层指定的节点
void preOrder2Left(BinTree *root,int height) //非递归前序遍历
{
stack<BinTree*> s;
BinTree *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
if(p->height==height) cout<<p->data<<" ";
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rchild;
}
}
}
上面的先序遍历我们只能打印从左到右同层元素,要是打印从右到左同层元素我们还要再改写一次,只是将遍历顺序变了一下即变成”右左中“的伪先序遍历我们称为preOrder2Right(BinTree *root,int height),放的元素和先序一样只是顺序相反而已(先放右在放左了),相信你一定可以写出来的
于是我们的主函数就可以这样写了
int main(){
BinaryTreeNode *r;
int depth = getDepth(r);
for(int i=0;i<depth;i++){
if(i%2) preOrder2Right(r,i);
else preOrder2Left(r,i);
}
}
不知道你们有什么收获,我们共同进步