码迷,mamicode.com
首页 > 编程语言 > 详细

设计一个算法,输出从每个叶子节点到根节点的逆路径

时间:2015-07-06 18:10:15      阅读:493      评论:0      收藏:0      [点我收藏+]

标签:二叉树   逆路径   层次遍历   后序遍历   path数组   

下面使用三种遍历方法输出逆路径,假设二叉树采用二叉链存储结构存储。

方法1:采用基于层次遍历的方法,设计的队列为非环形顺序队列,将所有已扫描的节点指针进队,并在队列中保存双亲节点的位置。当找到一个叶子节点时,在队列中通过双亲节点的位置输出该叶子节点到根节点的逆路径。对应的算法如下:

void AllPath(BTNode * b)

{

struct snode

{

BTNode *node; //存放当前节点指针

int parent; //存放双亲节点在队列中的位置

} Qu[MaxSize]; //定义非循环队列

int front,rear,p; //定义队头和队尾指针

front=rear=-1; //置队列为空队列

rear++;

Qu[rear].node=b; //根节点指针进队

Qu[rear].parent=-1; //根节点没有双亲节点

while(front<rear) //队列不为空

{

front++; //front为当前出队节点的下标

b=Qu[front].node; //队头出队

if(b->lchild==NULL&&b->rchild==NULL) //*b为叶子节点

{

printf("%c到根节点逆路径:",b->data);

p=front;

while(Qu[p].parent!=-1)

{

printf("%c\n",Qu[p].node->data);

p=Qu[p].parent;

}

printf("%c\n",Qu[front].node->data);

}

if(b->lchild!=NULL) //左孩子进队

{

rear++;

Qu[rear].node=b->lchild;

Qu[rear].parent=front;

}

if(b->rchild!=NULL) //右孩子进队

{

rear++;

Qu[rear].node=b->rchild;

Qu[rear].parent=front;

}

}

}

方法2:采用后序遍历非递归算法,将访问的某个节点改为:判断该节点*p是否为叶子节点,若是叶子节点,则输出栈中所有节点的值构成从该节点到根节点的逆路径。对应的非递归算法如下:

void AllPath(BTNode * b)

{

BTNode *St[MaxSize]; //定义一个顺序栈

BTNode *p=b,*q;

int flag,top=-1,i; //栈指针置空值

if(b!=NULL)

{

do

{

while(p!=NULL) //将*p的所有左节点进栈

{

top++;

St[top]=p;

p=p->lchild;

}

q=NULL; //q指向栈顶节点的前一个已访问的节点

flag=1; //设置flag=1表示处理栈顶节点

while(top!==-1&&flag==1)

{

p=St[top]; //取出当前栈顶元素

if(p->rchild==q) //右孩子不存在或者已被访问,访问之

{

if(p->lchild==NULL&&p->rchild==NULL) //叶子节点

{

printf("%c到根节点的逆路径:",p->data);

for(i=top;i>=0;i--)

printf("%c ",St[i]->data);

printf("\n");

}

top--;

q=p; //q指向刚刚访问的节点

}

else

{

p=p->lchild; //p指向右孩子节点

flag=0; //设置flag=0表示栈顶节点处理完毕

}

}

}while(top!=-1);

printf("\n");

}

}

方法3:采用path数组存放路径,pathlen整数存放路径长度。设f(b,path,pathlen)的功能是输出二叉树b中所有叶子节点到根节点的逆路径,需要借助于path和pathlen两个形参实现算法。对应的递归模型如下:

技术分享

对应的递归算法如下:

void AllPath(BTNode *b,ElementType path[ ],int pathlen) //初始调用时path所有元素为空,pathlen为0,b

{  //为根节点指针

int i;

if(b!=NULL)

{

if(b->lchild==NULL&&b->rchild==NULL)

{

printf("%c到根节点的逆路径:%c ",b->data,b->data);

for(i=pathlen-1;i>=0;i--)

printf("%c ",path[i]);

printf("\n");

}

else

{

path[pathlen]=b->data; //将当前节点放入路径中

pathlen++; //路径长度增1

AllPath(b->lchild,path,pathlen); //递归扫描左子树

AllPath(b->rchild,path,pathlen); //递归扫描右子树

pathlen--; //恢复环境

}

}

}

对于如图所示的二叉树,求每个叶子节点到根节点的路径的结果如图所示。

技术分享

版权声明:本文为博主原创文章,未经博主允许不得转载。

设计一个算法,输出从每个叶子节点到根节点的逆路径

标签:二叉树   逆路径   层次遍历   后序遍历   path数组   

原文地址:http://blog.csdn.net/wuruiaoxue/article/details/46774171

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!