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

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

方法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两个形参实现算法。对应的递归模型如下:

设计一个算法,输出从每个叶子节点到根节点的逆路径_第1张图片

对应的递归算法如下:

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数组)