下面使用三种遍历方法输出逆路径,假设二叉树采用二叉链存储结构存储。
方法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--;//恢复环境
}
}
}
对于如图所示的二叉树,求每个叶子节点到根节点的路径的结果如图所示。