数据结构:树的链式递归实现

/************************************************************************
树链式递归实现

函数: 
build

getsum(获取树得节点个数) 
getdep(获取树的深度 ) 
getlson(查找某一个节点的左子树) 
getrson(查找某一个节点的右子树) 
getparent(查找某一个节点的父亲) 

preprint(前序遍历) 
inprint(中序遍历) 
postprint(后序遍历) 

************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<math.h> 
int max(int x,int y)
{
	if (x>y) return x;return y;
}
typedef struct binode
{
	char data;
	struct binode *lson,*rson;
} *bitree;

//第一种build的方法,直接在函数内部初始化T 
void build(bitree *T)//*T表示传递进来的这个指针,T表示二级指针。我们进行操作的是*T。 
{
	char ch;
	scanf("%c",&ch);
	if (ch=='^')
	{
		(*T)=NULL;//若该位置为None,将指针置为空,否则该指针因未初始化导致指向完全随机 
		return;
	}
	*T=(bitree)malloc(sizeof(struct binode));//为指针分配空间。
	//注意这里是分配指向大小为struct binode空间的指针,不是分配大小为sizeof(bitree)的空间  (bitree是一个指针)
	(*T)->data=ch;
	//printf("%c",(*T)->data);
	bitree leftson,rightson;//新建两个指针 	
	build(&leftson);
	build(&rightson);
	(*T)->lson=leftson;
	(*T)->rson=rightson;//注意这里要先build再赋值
}

//第二种build的方法,传二级指针,然后通过返回bitree给T赋值 
bitree build2(bitree *T)//*T表示传递进来的这个指针,T表示二级指针。我们进行操作的是*T
{
	char ch;
	scanf("%c",&ch);
	if (ch=='^')
	{		
		return(NULL);
	}
	*T=(bitree)malloc(sizeof(struct binode));//为指针分配空间,注意不是分配大小为sizeof(bitree)的空间 
	(*T)->data=ch;
	
	(*T)->lson=build2(&((*T)->lson));
	(*T)->rson=build2(&((*T)->rson));
	return (*T);
}

//第三种build的方法,只需要传一级指针,然后通过返回bitree给T赋值。
//因为T最后是在主程序里赋值,所以我们可以先假装在build3里修改地址,然后将修改后的结果返回,最后在主程序里更新。这样更简洁 
bitree build3(bitree T)//T表示传递进来的这个指针
{
	char ch;
	scanf("%c",&ch);
	if (ch=='^')
	{		
		return(0);
	}
	//printf("%p\n",T);
	T=(bitree)malloc(sizeof(struct binode));//为指针分配指针空间 
	//printf("%p\n",T);
	T->data=ch;	
	T->lson=build3(T->lson);
	T->rson=build3(T->rson);
	return T;
}

//get property
int getsum(bitree *T)
{
	if (!(*T)) return 0;
	return 1+getsum(&(*T)->lson)+getsum(&(*T)->rson);
}
int getdep(bitree *T)
{
	if (!(*T)) return 0;
	return 1+max(getdep(&(*T)->lson),getdep(&(*T)->rson));
}
void getparent(bitree *T,char target,char parent)
{
	if (!(*T)) return;
	if ((*T)->data==target)
	{
		printf("%c",parent);
		return;	
	}
	getparent(&(*T)->lson,target,(*T)->data);
	getparent(&(*T)->rson,target,(*T)->data);
}
void getlson(bitree *T,char target)
{
	if (!(*T)) return;
	if ((*T)->data==target)
	{
		if ((*T)->lson) printf("%c",((*T)->lson)->data);
		return;	
	}
	getlson(&(*T)->lson,target);
	getlson(&(*T)->rson,target);
}
void getrson(bitree *T,char target)
{
	if (!(*T)) return;
	if ((*T)->data==target)
	{
		if ((*T)->rson) printf("%c",((*T)->rson)->data);
		return;	
	}
	getrson(&(*T)->lson,target);
	getrson(&(*T)->rson,target);
}

//traverse
void preprint(bitree T)
{
	if (!(T)) return;	
	printf("%c",T->data);
	preprint(T->lson);
	preprint(T->rson);
}
//第二种preprint,因为不用修改指针,其实可直接传该指针,这样更为简洁。traverse和getproperty都能改写 
void preprint2(bitree *T)
{
	if ((*T)==NULL) return;
	printf("%c",(*T)->data);
	preprint2(&((*T)->lson));	
	preprint2(&((*T)->rson));
}

void inprint(bitree *T)
{
	if (!(*T)) return;
	inprint(&((*T)->lson));
	printf("%c",(*T)->data);
	inprint(&((*T)->rson));
}
void postprint(bitree *T)
{
	if (!(*T)) return;	
	postprint(&((*T)->lson));
	postprint(&((*T)->rson));
	printf("%c",(*T)->data);
}


int main()
{
/*  input:  ABC^^D^^^
*
*      A
*    B   ^
*   C D
*  ^^ ^^
*
*/
	bitree T;//新建一个指针 
	build(&T);//传递这个指针的地址。如果这里写成build(T)然后在build程序直接调用T,则无法修改T的值(二级指针才能修改指针地址) 
	//T=build2(&T);//另外的方式 
	//T=build3(T);//另外的方式 
	printf("pre-order traverse:\n");
	preprint(T);
	printf("\n");

	printf("in-oder traverse:\n");
	inprint(&T);
	printf("\n");
		
	printf("post-order traverse:\n");
	postprint(&T);
	printf("\n");
	
	printf("depth of tree:\n");
	printf("%d",getdep(&T));
	printf("\n");
	
	printf("number of node:\n");
	printf("%d",getsum(&T));
	printf("\n");
	
	printf("get parent:\n");
	getparent(&T,'C','^');
	printf("\n");
	
	printf("get leftson:\n");
	getlson(&T,'A');
	printf("\n");
	
	//pretest pass
}

猜你喜欢

转载自www.cnblogs.com/reshuffle/p/12791063.html