下面使用三种遍历方法输出逆路径,假设二叉树采用二叉链存储结构存储。
方法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--; //恢复环境
}
}
}
对于如图所示的二叉树,求每个叶子节点到根节点的路径的结果如图所示。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/wuruiaoxue/article/details/46774171