题目:
求给定二叉树中的所有路径~
分析:求给定二叉树的所有路径,即把所有结点数据存放到一个二维数组即可,ok,话不多说,风吹pp凉,咱们直接上高速~
-
树的结构体
typedef char ElemType;
typedef struct BinNode{
ElemType data;
struct BinNode *lchild,*rchild;
}BinNode,*BinTree;
这东西想必大家都很熟悉了,不多说~ 不熟悉的可以看我之前的博客二叉树的最大宽度_m0_嘉木的博客-CSDN博客
-
先序遍历创建树
//先序创建二叉树
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));
}
}
不懂的接着看博客-->二叉树的最大宽度_m0_嘉木的博客-CSDN博客
OK,那么写到这里本题的关键点就来了~
-
所有路径
int r_len=0,l_len=-1,max=0,flag=0;//r_len,l_len分别代表二维数组path的行和列
void AllPath(BinTree T,int path[MAX][MAX])
{
int i;
if(T)//树不空
{
if(r_len && flag)//不是第0行,并且flag=1
{
for(i=0;i<=r_len;i++)
{
path[r_len][i]=path[r_len-1][i];//把上一行的元素复制到这一行
flag=0;
}
}
path[r_len][++l_len]=T->data;//l_len+1,结点放入数组
if(l_len>max)//大于最大的元素个数则替换
max=l_len;
T->data=1;//data=1表示此树结点已经访问过了
AllPath((BinTree)T->lchild,path);//递归访问左子树
if(!T->lchild && !T->rchild)//叶子结点
{
r_len++;//行+1
flag=1;
}
AllPath((BinTree)T->rchild,path);//递归访问右子树
if(T->data==1) l_len--;//列指针回退
}
}
分析:简单描述一个例子(如图),r_len和l_len就是二维数组path的行和列,max为所有路径中最长路径的长度(其实对于这题来说并没有什么用,不想要的可以自行舍去),flag表示需不需要复制元素(这个后面会讲到)。首先根节点空不空,不空则ll_en+1=0,并把元素存放到数组,T->data=1(表示根节点已经访问过了),然后递归调用左子树,左子树也不空则继续 存放到数组l_len=1,继续调用B的左子树,为空,则退出,执行下面的if语句,由于B是叶子结点,所以r_len++,开辟一行新的数组,flag=1(需要复制),然后B的右子树,为空,退出,B已经访问过了,所以l_len--=0,此时path[0]行的元素为(A ,B)然后则是A的右子树,由于r_len和flag都不是0,则需要把上一行的数组复制到这一行,即A,再把C存放到数组,依次执行C的左子树,C的右子树...最后输出结果即可~
-
完整代码
#include<stdio.h>
#include<stdlib.h>
#define MAX 256
typedef char ElemType;
typedef struct BinNode{
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 r_len=0,l_len=-1,max=0,flag=0;//r_len,l_len分别代表二维数组path的行和列
void AllPath(BinTree T,int path[MAX][MAX])
{
int i;
if(T)//树不空
{
if(r_len && flag)//不是第0行,并且flag=1
{
for(i=0;i<=r_len;i++)
{
path[r_len][i]=path[r_len-1][i];//把上一行的元素复制到这一行
flag=0;
}
}
path[r_len][++l_len]=T->data;//l_len+1,结点放入数组
if(l_len>max)//大于最大的元素个数则替换
max=l_len;
T->data=1;//data=1表示此树结点已经访问过了
AllPath((BinTree)T->lchild,path);//递归访问左子树
if(!T->lchild && !T->rchild)//叶子结点
{
r_len++;//行+1
flag=1;
}
AllPath((BinTree)T->rchild,path);//递归访问右子树
if(T->data==1) l_len--;//列指针回退
}
}
int main()
{
BinTree T;
printf("创建树输入树T的先序序列(其中使用#代表空节点)\n");
CreateBinTree(&T);
InOrderTraverse(T);
printf("\n");
int path[MAX][MAX]={0},i,j;
AllPath(T,path);
printf("路径为:\n");
//printf("%d--%d\n",max,r_len);
for(i=0;i<r_len;i++)
{
for(j=0;j<=max;j++)
if(path[i][j]!=0)
printf("%c->",path[i][j]);
printf("NULL\n");
}
return 0;
}
注:有错误的话直接扣me~