二叉树之二--普通二叉树代码实现

    话说吧,人有时候就是很笨,当然这里说我自己呢,呵呵,最近学数据结构学到了普通的二叉树,线索二叉树,还有赫夫曼二叉树,几乎是每一部分的知识看了三遍才基本能够清晰的知道其实现原来是什么,怎么来的,怎么去用!哎可能真的是笨,所以特作此笔记记录下来首先是普通二叉树关于普通二叉树的基本知识可见一位博主的文章理论知识讲的很详细,查看一下代码是<零基础学算法>这书上的大部分都相同,但是有少部分不同,主要是自己理解了之后慢慢敲上去的,特此做个笔记!
     头文件中的结构体申明:

         

#define QUEUE_MAXSIZE 50
typedef  int  TreeDepth ;

typedef struct ChainTree
{
	char dat;
	 struct ChainTree *Left;
	 struct ChainTree *Right;
}ChainBinTree;


ChainBinTree* InitBinTree();                                  //初始化产生一个二叉树的根节点并返回一个根节点指针
int           AddBinNode(ChainBinTree *T);                    //添加到当前根节点的左子树还是右子树0,左,1 右
TreeDepth     GetBinTreeDepth(ChainBinTree* T);                //获取树的深度
int           FindData(ChainBinTree *T,char dat);               //查找树种是否存在dat数据
int           BinTreeSearch(ChainBinTree *T,int SearchType);    //Search指明遍历树的方式  
void          ReleaseTree(ChainBinTree *T);                                 //释放二叉树所占的资源                            
 
  函数的实现代码:
   
//实现函数
//1.初始化二叉树
ChainBinTree* InitBinTree()
{
	ChainBinTree *p;                //测试不用指针可否ChaiBinTree
    if(!(p=(ChainBinTree*)malloc(sizeof(ChainBinTree))))
	{
		printf("创建节点失败!\n");
		exit(-1);
	}

	printf("输入根节点数据!\n");
	scanf("%c",&p->dat);
	p->Left=NULL;
	p->Right=NULL;
	return p;
}

//2.添加树节点
int AddBinNode(ChainBinTree* T)
{
	 int LorR;
     ChainBinTree *Node;

	 if(T)
	 {
	    if(! (Node=(ChainBinTree*)malloc(sizeof(ChainBinTree)))  )
		{
		    printf("创建子节点失败!\n");
		    exit(-1);
		}
		fflush(stdin);
        printf("请输入节点数据!\n");
		scanf("%c",&Node->dat);
		Node->Left=NULL;
		Node->Right=NULL;

	    printf("要添加到左子树(0)--还是右子树(1)!\n");
        scanf("%d",&LorR);

		switch(LorR)
		{
		case 0:
		   if(T->Left)
		   {
			   printf("左子树非空!\n");
			   return 0;
		   }
		   else
			   T->Left=Node;
		  break;
		case 1:
			if(T->Right)
			{
               printf("右子树非空!\n");
			   return 0;
			}
		   else
			   T->Right=Node;
		  break;
		}

	 }
	 else
	 {
		 printf("当前根节点为空,添加失败!\n");
		 return 0;
	 }
	return 1;
}

//3.获取到树的深度
TreeDepth  GetBinTreeDepth(ChainBinTree* T)
{
    int depth1,depth2;

	if(T)
	{
         depth1=GetBinTreeDepth(T->Left);
		 depth2=GetBinTreeDepth(T->Right);
		 //depth=depth1>depth2 ? depth1 : depth2;
		 if(depth1>depth2)
			 return depth1+1;
		 else
			 return depth2+1;
	}
		return 0;
}
//4.查找二叉树中的数据
int  FindData(ChainBinTree *RootTree,char dat)
{
   if(RootTree)
   {
	   if(RootTree->dat==dat)
		   return 1;
	   else if(FindData(RootTree->Left,dat))
		      return 1;
	   else if(FindData(RootTree->Right,dat))
	          return 1;
	   else 
				  return 0;
   }
   else
	   return 0;
  
}
//5.遍历二叉树
int   BinTreeSearch(ChainBinTree *T,int SearchType)
{
	int head=0,tail=0;                 //按层遍历中的数据
    ChainBinTree *p=NULL;
    ChainBinTree *q[QUEUE_MAXSIZE];
	switch(SearchType)
	{
		//先序遍历  中--左--右
	case 0:
		 if(T)
		 {
		    printf("%c ",T->dat);
		    BinTreeSearch(T->Left,SearchType);
		    BinTreeSearch(T->Right,SearchType);
		 }
		 else
			 return 0;
		break;
		//中序遍历  左--中--右
	case 1:
		 if(T)
		 {
		    BinTreeSearch(T->Left,SearchType);
			printf("%c ",T->dat);
		    BinTreeSearch(T->Right,SearchType);
		 }
		 else
			 return 0;
		break;
		//后续遍历  左--右--中
	case 2:
	
		 if(T)
		 {
		    BinTreeSearch(T->Left,SearchType);
		    BinTreeSearch(T->Right,SearchType);
			printf("%c ",T->dat);
		 }
		 else
			 return 0;
		break;
		//按层遍历
	case 3:
         if(T)
		 {
			 tail=(tail+1)%QUEUE_MAXSIZE;		
			 q[tail]=T;
		 }
		 while(head!=tail)
		 {
			 head=(head+1)%QUEUE_MAXSIZE;
			 p=q[head];
			 printf("%c ",p->dat);
			 if(NULL!=p->Left)
			 {
				 tail=(tail+1)%QUEUE_MAXSIZE;
				 q[tail]=p->Left;
			 }
			 if(NULL!=p->Right)
			 {
				 tail=(tail+1)%QUEUE_MAXSIZE;
				 q[tail]=p->Right;
			 }
		 }
		break;
	}
	return 1;
}
//6.释放二叉树资源,即清空二叉树
void  ReleaseTree(ChainBinTree *T)
{
	if(T)
	{
		ReleaseTree(T->Left);
		ReleaseTree(T->Right);
		free(T);
	}
	else
		return;
}
  这几种树种我看就算这个树,最好理解了,最主要是递归的了,应该比较简单!其中我将四种遍历方式整合到一个函数BinTreeSearch()了.
  主函数测试:
     
int main(int argc,char* argv[])
{
	ChainBinTree *p;
	int Select,type;
	char ch;
    p=InitBinTree();

	while(1)
	{
	    printf("0--添加节点      1--求树的深度\n");
     	printf("2--查找数据      3--遍历树\n");
		printf("4--结束操作\n");
    	printf("请输入要选择的操作\n");
        fflush(stdin);
    	//scanf("%d",&Select);
		scanf("%d",&Select);
	
        switch(Select)
		{
		case 0:
	        if( AddBinNode(p))
				printf("添加节点成功!\n");
			break;
		case 1:
			printf("当前树的深度是:%d\n",GetBinTreeDepth(p));
			break;
		case 2:
			fflush(stdin);
            printf("请输入要查找的数据\n");
			scanf("%c",&ch);
			if(FindData(p,ch))
				printf("查找成功,该数据在树种\n");
			else
				printf("查找失败!\n");
			break;
		case 3:
			printf("请选择遍历方式\n");
			printf("0--先序遍历  1--中序遍历  2--后续遍历  3--按层遍历\n");
		//	fflush(stdin);
			scanf("%d",&type);
			BinTreeSearch(p,type);
			break;
		case 4:
			ReleaseTree(p);
			return 0;
		}
		printf("\n");
	 }
	return 0;
}

    对了,上述还有点细节需要注意,本人菜鸟就是不知道为什么必须要用fflush(stdin)来刷新缓冲流,才能使输入生效,这个我还得去查查,另外今天做实验有个scanf的问题也值得注意,以后写个关于scanf的总结再说这个吧!
   竟忘了关于这个代码以及线索二叉树的代码已经上传 没资料的同学可以看下下载代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值