题目:
求任意二叉树中第一条最长的路径长度,并输出此路径上各节点的值。
分析:求路径长度,我们都知道肯定是从根节点出发,那么怎么样才算是路径的终点呢?其实就是叶子结点,每一个叶子结点就是每条路径的终点,所以只要找到叶子结点此条路径就算结束了。基本思路就是遍历树的每一条路径,记录长度,和当前最长路径比较,大于则替换,最终求出最长路径即可~
-
定义树的结构体
typedef char ElemType;
typedef struct BiNode{
ElemType data;
struct BinNode *lchild,*rchild;
}BinNode,*BinTree;
lchild和rchild分别代表树的左孩子和右孩子,BinTree为结构体指针; 基本操作,不过多解释好吧~
-
先序创建二叉树
//先序创建二叉树
void CreateBinTree(BinTree *T)
{
ElemType ch;
if((ch=getchar())=='#') *T=NULL;
else
{
(*T)=(BinTree)malloc(sizeof(BinNode));
(*T)->data=ch;
CreateBinTree((BinTree *)&((*T)->lchild));
CreateBinTree((BinTree *)&((*T)->rchild));
}
}
由于T本身就是指针类型,再传入一个指针即(**T),所以对T进行解引用操作;递归调用函数时(BinTree *)表示强制类型转换。用'#'表示空
-
先序遍历
//先序遍历二叉树
void InOrderTraverse(BinTree T)
{
if(T)
{
printf("%c",T->data);
InOrderTraverse((BinTree)(T->lchild));
InOrderTraverse((BinTree)(T->rchild));
}
}
递归左右子树输出结点数据
-
最长路径
void longest_path(BinTree T,int *path,int *longestpath)
{
int j;
if(T)//树不空
{
if(!T->lchild && !T->rchild)//当遇到叶子结点时,该条路径完毕
{
path[len]=T->data;//把结点数据放入数组
if(len>longest_len)//如果长于longest_len就替换
{
for(j=0;j<=len;j++)//把路径复制到longestpath里面
longestpath[j]=path[j];
longest_len=len;//longest_len更新
}
}
else//当遇到的不是叶子结点时,该条路径继续
{
path[len++]=T->data;//结点放入数组,len++
longest_path((BinTree)T->lchild,path,longestpath);
longest_path((BinTree)T->rchild,path,longestpath);
len--;//每次退出递归len--
}
}
}
判断树是否为空,空则返回。这里用到了两个数组path和longestpath分别表示当前遍历的路径和最长的路径。len和longest_len表示当前路径长度和最长的路径长度。遇到叶子结点代表此条路径遍历结束,把此条路径与最长路径进行比较,若大于则替换。若不是叶子结点,则把数据放到数组,len++,再依次递归遍历左子树和右子树,每次递归结束,len--,退回原来根节点,最后输出longest_len即可~
-
完整代码
#include<stdio.h>
#include<stdlib.h>
#define MAX 200
typedef char ElemType;
typedef struct BiNode{
ElemType data;
struct BinNode *lchild,*rchild;
}BinNode,*BinTree;
//先序创建二叉树
void CreateBinTree(BinTree *T)
{
ElemType ch;
if((ch=getchar())=='#') *T=NULL;
else
{
(*T)=(BinTree)malloc(sizeof(BinNode));
(*T)->data=ch;
CreateBinTree((BinTree *)&((*T)->lchild));
CreateBinTree((BinTree *)&((*T)->rchild));
}
}
//先序遍历二叉树
void InOrderTraverse(BinTree T)
{
if(T)
{
printf("%c",T->data);
InOrderTraverse((BinTree)(T->lchild));
InOrderTraverse((BinTree)(T->rchild));
}
}
int len=0;
int longest_len=0;
void longest_path(BinTree T,int *path,int *longestpath)
{
int j,i;
if(T)//树不空
{
if(!T->lchild && !T->rchild)//当遇到叶子结点时,该条路径完毕
{
path[len]=T->data;//把结点数据放入数组
if(len>longest_len)//如果长于longest_len就替换
{
for(j=0;j<=len;j++)//把路径复制到longestpath里面
longestpath[j]=path[j];
longest_len=len;//longest_len更新
}
}
else//当遇到的不是叶子结点时,该条路径继续
{
path[len++]=T->data;//结点放入数组,len++
longest_path((BinTree)T->lchild,path,longestpath);
longest_path((BinTree)T->rchild,path,longestpath);
len--;//每次退出递归len--
}
}
}
int main()
{
int i;
BinTree T;
printf("创建树输入树T的先序序列(其中使用#代表空节点)\n");
CreateBinTree(&T);
InOrderTraverse(T);
printf("\n");
int path[MAX]={0};//存放每个结点路径
int longestpath[MAX]={0};//最长结点路径
longest_path(T,path,longestpath);
printf("第一条最长的路径长度为:%d\n",longest_len+1);
printf("路径为:");
for(i=0;i<=longest_len;i++)
printf("%c ->",longestpath[i]);
printf("NULL");
return 0;
}