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

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

方法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--;
//恢复环境

}

}

}

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

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

时间: 2024-08-07 23:27:38

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

设计一个算法,採用BFS方式输出图G中从顶点u到v的最短路径(不带权的无向连通图G採用邻接表存储)

思想:图G是不带权的无向连通图.一条边的长度计为1,因此,求带顶点u和顶点v的最短的路径即求顶点u和顶点v的边数最少的顶点序列.利用广度优先遍历算法,从u出发进行广度遍历,类似于从顶点u出发一层一层地向外扩展,当第一次找到顶点v时队列中便包括了从顶点u到顶点v近期的路径,如图所看到的,再利用队列输出最路径(逆路径),所以设计成非循环队列. 相应算法例如以下: typedef struct  { int data;//顶点编号 int parent;//前一个顶点的位置 } QUEUE;//非循环

设计一个算法,采用BFS方式输出图G中从顶点u到v的最短路径(不带权的无向连通图G采用邻接表存储)

思想:图G是不带权的无向连通图,一条边的长度计为1,因此,求带顶点u和顶点v的最短的路径即求顶点u和顶点v的边数最少的顶点序列.利用广度优先遍历算法,从u出发进行广度遍历,类似于从顶点u出发一层一层地向外扩展,当第一次找到顶点v时队列中便包含了从顶点u到顶点v最近的路径,如图所示,再利用队列输出最路径(逆路径),所以设计成非循环队列. 对应算法如下: typedef struct  { int data; //顶点编号 int parent; //前一个顶点的位置 } QUEUE; //非循环队

A、B两个整数集合,设计一个算法求他们的交集

代码留作记录,本人水平有限,看了别人的解法真是自愧不如. 关于此题的详细探讨可以参考:http://blog.csdn.net/thebestdavid/article/details/12056293 /*A.B两个整数集合,设计一个算法求他们的交集,尽可能的高效.*/ #include <iostream> #include <cstring> #include <set> #define M 8 #define N 5 using namespace std; i

剑指offer系列——二维数组中,每行从左到右递增,每列从上到下递增,设计一个算法,找其中的一个数

题目:二维数组中,每行从左到右递增,每列从上到下递增,设计一个算法,找其中的一个数 分析: 二维数组这里把它看作一个矩形结构,如图所示: 1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 在做这道题的时候我最先考虑的是每次比较对角线上的元素可能可以取得较好的效果, 以查找9为例, 从1(0,0)开始,1<10,可以得出结论,10在1的右侧或下侧: 1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 然后看4(1,1),4<9, 1 2 8 9 2

(DS 《算法竞赛入门经典》)LA 3027 Corporative Network(查询某一个节点到根节点之间的距离)

题目大意: 查询某一个节点到根节点之间的距离 解题思路: 加权并查集问题.之前做的题目是"查看两个或多个节点是否在同一个集合下",现在的题目是"查询某个节点到 根节点之间的距离".之前只需要使用到father[x]这个数组,用来表示x的父亲节点是谁.现在引入dist[x]数组,用来记录 x节点到根节点的距离 1)在并查集中,根节点不懂,其他节点都可以动. A very big corporation is developing its corporative net

第4章第1节练习题12 删除以指定节点为根节点的所有子树

问题描述 已知二叉树以二叉链表存储,编写算法完成对于树中每一个元素值为x的节点,删去以它为根的子树,并释放相应空间 算法思想 本题可以分成两个部分来完成.第一步:查找值为x的节点:第二步:删除以值为x的节点为根节点的所有子树: 因为删除的是x的所有子树,因此遍历方式应该选择自上而下的遍历方式,即先序遍历或层次遍历方式,这里选择层次遍历的方式实现. 删除值为x的节点的所有子树,可以考虑使用递归的方式: 即此时可以认为删除的是以值为x的节点作为根节点的树: 首先删除该树的叶子节点,这样该树的倒数第二

C#中treeview的问题,如何区分根节点和子节点以及根节点和根节点的兄弟节点?

根节点的Level属性为0,一级子节点Level属性为1,二级子节点Level属性为2,以此类推:同级节点可以用索引.名称.文本来区分.用索引区分根节点时,TreeView.Nodes[0]就是第一个根节点,TreeView.Nodes[1]就是第二个根节点,以此类推:用索引区分一级子节点时,TreeView.Nodes[0].Nodes[0]为第一个根节点的第一个子节点,TreeView.Nodes[0].Nodes[1]是第一个根节点的第二个子节点,以此类推: 2.如何获取TreeView点

设计一个算法将一个顺序表逆置

#include<iostream> #include<malloc.h> using namespace std; typedef struct { int length;//保存长度 int data[40];//数组 } SqList; /*算法1:设计一个高效的算法,将顺序表中的所有元素逆置.要求算法空间股咋度为o(1)*/ //初始化顺序表 void initReverse(SqList &s,int *a,int l){ s.length=0; //插入元素 f

设计一个算法,求非空二叉树中指定的第k层(k&gt;1)的叶子节点的个数

思想:采用基于层序遍历的方法.用level扫描各层节点,若某一层的节点出队后,rear指向该层中最右节点,则将rear赋值给last(对于第一层,last=1).在出队时,若front=last,表示这一层处理完毕,让层号level增1,并置last为下一层最右节点.那么如何求一层的最右节点呢?这是因为第一层只有一个节点,它就是最右节点.对于其他层,上一层最右节点最后进队的孩子一定是该层的最右节点. 例如,对于如图所示的二叉树,求k=3的叶子节点个数的过程如下:level=1;A进队时rear=