二叉树的各种操作的(递归非递归)的实现,如(递归非递归)先序后序中序层次遍历 二叉树的高度 叶子节点数,所有节点数

18 篇文章 0 订阅
//BinaryTree.h

#define CHAR
//当CHAR定义时,用字符的处理模式
//当CHAR没有被定义时,采用整数处理模式
#ifdef CHAR
//数据类型的定义
typedef char DataType;
#else
typedef int Datatype;
#endif

#define true 1
#define false 0
typedef int bool;


//二叉树的链式存储结构
typedef struct BiTNode
{
	DataType data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
} BiTNode,* BiTree;




//队列的链式存储结构


//队列节点存储结构
typedef struct Node
{
	//DataType data;
	BiTree ptr;
	struct Node *next;
} Node, *pNode;

//队列存储结构
typedef struct Queue
{
	pNode front;
	pNode rear;
	int queuesize;
} LinkQueue, *pLinkQueue;



//栈节点类型
typedef struct StackNode
{
	BiTree ptr;
	struct StackNode *next;
}  StackNode,*pStackNode;

//栈类型
typedef struct LinkStack
{
	pStackNode top;
	int stacksize;
} LinkStack,*pLinkStack;

pLinkStack  InitLinkStack()
{
	pLinkStack s=(pLinkStack) malloc(sizeof( LinkStack)) ;
	if(!s) 
	{
		s->stacksize=0;
		s->top=NULL; 
	}
	return s;
}

void ClearLinkStack(pLinkStack s)
{
	BiTree ptr;
	while( s->stacksize )
	{
		Pop(s,&ptr);
	}

}

void DestroyLinkStack(pLinkStack s)
{
	if( s->stacksize)
		ClearLinkStack(s);
	free(s);
}

void Push(pLinkStack s,BiTree ptr )
{
	pStackNode p=(pStackNode ) malloc( sizeof(StackNode)) ;
	if( !p )
		exit(-1);
	p->ptr=ptr;
	p->next=NULL;
	p->next=s->top ;
	s->top=p;
	s->stacksize++;
}

void Pop(pLinkStack s,BiTree *ptr)
{
	if(s->stacksize==0)
	{
		printf("the linkstack is null.can't pop anything\n");
                ptr=NULL;
	}
	else 
	{

		pStackNode p=s->top;
		*ptr=p->ptr ;
		s->top=s->top->next;
		s->stacksize--;
		free(p);
	}
}

int  GetLinkStackSize(pLinkStack s)
{
	return s->stacksize;
}

BiTree GetTop(pLinkStack s )
{
	if(s->stacksize==0)
	{
		printf("the linkstack is null");
		return 0;
	}
	else
	{
		return s->top->ptr;
	}
}

int IsLinkStackEmpty(pLinkStack s)
{
	if(s->stacksize==0)
		return 1;

	else
		return 0;
}

void LinkStackTraverse(pLinkStack s, void (*Visit)(DataType data) )
{
	pStackNode p=s->top;
	while(p)
	{
		Visit(p->ptr->data) ;
		p=p->next;
	}
}
void print(DataType data)
{
	printf("%c",data);
}


/*
int main()
{
	pLinkStack s=InitLinkStack();

	int  i;
	printf("gettop :\n");
	for( i=0 ;i<100;i++)
	{
		Push(s,i);
		DataType datatop= GetTop(s);
		printf("%d ",datatop);
	}



	printf("\nIsLinkStackEmpty %d",IsLinkStackEmpty(s) );
	printf("\n traverse the LinkStack:\n");
	LinkStackTraverse(s ,print);
	printf("\n the current LinkStack' size :%d\n",GetLinkStackSize(s) );
	DataType data;
	Pop(s,&data);
	printf("Pop %d \n",data);

	printf("\n the current LinkStack' size :%d\n",GetLinkStackSize(s) );
	Pop(s,&data);
        printf("Pop %d \n",data);
	printf("LinkStack clear!\n");
	ClearLinkStack(s);
	printf("LinkStack destroy!\n");
	DestroyLinkStack(s);
}


*/






pLinkQueue InitLinkQueue()
{
	pLinkQueue q=(pLinkQueue ) malloc(sizeof(LinkQueue)) ;
	if(!q)
	{
		q->front=NULL;
		q->rear=NULL;
		q->queuesize=0;
	}
	return q;
}

int  IsLinkQueueEmpty(pLinkQueue q)
{
	if(q->queuesize ==0)
		return 1;
	else
		return 0;
}

int GetLinkQueueLength(pLinkQueue q)
{
	return q->queuesize;
}

void EnLinkQueue(pLinkQueue q, BiTree ptr)
{
	if( q )
	{
		pNode p=(pNode ) malloc(sizeof(Node) ) ;
		p->ptr=ptr;
		p->next=NULL;

		if(q->queuesize==0)   //刚开始时队列为空时,对队头指针进行赋值
		{
			q->front=p;
			q->rear=p;
		}
		else
		{
			q->rear->next=p;
			q->rear=p;
		}	
		q->queuesize++;

	}
}

void DeLinkQueue(pLinkQueue q,BiTree *ptr)
{
	if(q->queuesize==0)
	{
		printf("the queue is null,can't get anything\n"); 
	}
	else
	{
		if(q->front==q->rear) //只有一个节点时,无节点的情况上面已经考虑了
		{
			*ptr=q->front->ptr;
			free(q->front);
			q->front=NULL;
			q->rear=NULL;
		}
		else
		{
			pNode p=q->front;
			*ptr=p->ptr;
			q->front=q->front->next;
			free(p);
		}
		q->queuesize--;

	}
}

int   GetHead(pLinkQueue q,DataType *x)
{
	if(q->queuesize==0)
		return 0 ;
	else
	{
		*x= q->front->ptr->data;
		return 1 ;
	}

}

void LinkQueueTraverse(pLinkQueue q, void (*Visit) (DataType data) )
{
	if(!q)
		exit(-1);
	pNode p=q->front ;
	if(!p)
	{
		printf("the LinkQueue is null\n");
		return ;
	}
	while(p)
	{
		Visit(p->ptr->data);
		p=p->next ;
	}

}

void ClearLinkQueue(pLinkQueue q)
{
	BiTree ptr ;
	while(q->queuesize)
	{
		DeLinkQueue( q, &ptr );

	}
}

void DestroyLinkQueue(pLinkQueue q)
{
	if(q->queuesize!=0)
		ClearLinkQueue(q) ;
	free(q);
}







//BinartTree.c

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include"BinaryTree.h"


BiTree  CreateBiTree( )
{
	char ch=getchar();
	//	char ch;
	//	scanf("%c",&ch);
	if( ch=='#')
		return NULL;
	else
	{
		BiTree  bt=(BiTree) malloc( sizeof(BiTNode) );
		bt->data=ch;
		bt->lchild=CreateBiTree();
		bt->rchild=CreateBiTree();
		return bt;
	}

}

/*
 *
 *后序遍历形式销毁二叉树
 * */
void DestroyBiTree(BiTree root)
{
	if(root)
	{
		DestroyBiTree(root->lchild);
		DestroyBiTree(root->rchild);
		free(root);
	}

}

/*
 *
 * 采用先序遍历递归方式查找
 * */
BiTree SearchBiTree(BiTree root ,DataType x)
{
	if(!root)
		return NULL;
	else
	{
		if(root->data==x)
			return root;
		else
		{
			BiTree ptr;
			ptr= SearchBiTree(root->lchild ,x) ;
			if(ptr==NULL)
				return SearchBiTree(root->rchild ,x) ;
			else
				return ptr ;
		}
	}

}
/*
 *
 * 返回当前结点的左孩子
 * */
BiTree LchildNode(BiTree ptr)
{
	return ptr->lchild;
}


/*
 *
 *返回当前结点的右孩子
 * */
BiTree RchildNode(BiTree ptr)
{
	return ptr->rchild;
}
/*
 *
 *二叉树的查找采用中序遍历非递归方式
 *
 * */
BiTree SearchBiTree2(BiTree root ,DataType x)
{
	if(!root)
		return NULL;
	else
	{
		BiTree ptr=root;
		pLinkStack s=InitLinkStack();
		while(ptr || !IsLinkStackEmpty(s) )
		{
			if(ptr)
			{
				if(ptr->data==x)
					return ptr;
				else
				{
					Push(s ,ptr ) ;
					ptr=ptr->lchild;
				}
			}
			else
			{
				Pop(s, &ptr) ;
				ptr=ptr->rchild ;
			}

		}

		DestroyLinkStack(s) ;
		return ptr ;
	}
}


void Visit(char  ch)
{
	printf("%c ",ch);
}


void PreOrderTraverse(BiTree root )
{
	if( root)
	{
		Visit(root->data);
		PreOrderTraverse(root->lchild);
		PreOrderTraverse(root->rchild);
	}
}

void InOrderTraverse(BiTree root )
{
	if(root)
	{
		InOrderTraverse(root->lchild );
		Visit(root->data);             
		InOrderTraverse(root->rchild);
	}

}
/*
 *计算二叉树的高度
 *
 * */
int TreeHeight(BiTree root)
{
	if(root==NULL)
		return 0;
	else
	{
		int lheight= TreeHeight(root->lchild) ;
		int rheight= TreeHeight(root->rchild) ;
		return  (lheight>rheight ? lheight+1:rheight+1) ;
	}
}


/*
 *
 *采用非递归层次遍历的方式计算二叉树的高度
 * */
int  TreeHeight2( BiTree root )  
{
	if(!root)
		return 0;
	pLinkQueue q=InitLinkQueue();
	EnLinkQueue(q , root);  
	int height=1; //头节点入队列
	while(! IsLinkQueueEmpty(q )  )
	{
		BiTree ptr ;
		DeLinkQueue(q,&ptr );
		//	Visit(ptr->data);

		if(ptr->lchild)
			EnLinkQueue(q, ptr->lchild );
		if(ptr->rchild)
			EnLinkQueue(q, ptr->rchild);
		if( ptr->lchild || ptr->rchild)
			height++;

	}
	DestroyLinkQueue(q);
	return height;
}


/*
 *
 *非递归的中序遍历的形式计算二叉树的高度
 *
 * */
int  TreeHeight3( BiTree root )
{
	if(!root )
		return 0;
	BiTree ptr=root;
	pLinkStack s=InitLinkStack();
	int height=0;
	while( ptr  || !IsLinkStackEmpty(s) )     
	{
		if( ptr )
		{
			Push(s,ptr) ;
			ptr=ptr->lchild ;
			int stacksize=GetLinkStackSize(s);
			printf("stacksize :%d\n",stacksize);
			height=height > stacksize ? height :stacksize ;  //其实二叉树的高度等于栈的最大深度 这样是错误的,当是后序遍历的时候成立
		}
		else 
		{
			Pop(s,&ptr ) ;
			//Visit(ptr->data);
			ptr=ptr->rchild;
		}

	}   

	DestroyLinkStack(s);
	return height;
}



void PostOrderTraverse(BiTree root )
{
	if( root)
	{
		PostOrderTraverse(root->lchild);
		PostOrderTraverse(root->rchild);
		Visit(root->data);
	}
}

bool IsTreeEmpty(BiTree root)
{
	if(root==NULL)
		return false;
	else
		return true;
}

void LevelOrderTraverse(BiTree root)  //队列
{
	if(!root)
		return ;
	pLinkQueue q=InitLinkQueue();
	EnLinkQueue(q , root);  
	while(! IsLinkQueueEmpty(q )  )
	{
		BiTree ptr ;
		DeLinkQueue(q,&ptr );
		Visit(ptr->data);

		if(ptr->lchild)
			EnLinkQueue(q, ptr->lchild );
		if(ptr->rchild)
			EnLinkQueue(q, ptr->rchild);

	}
	DestroyLinkQueue(q);
}


//非递归形式的先序遍历

void  PreOrderTraverse2(BiTree root)
{
	if( !root)
		return;
	BiTree ptr=root;
	pLinkStack s=InitLinkStack();

	while ( ptr ||  ! IsLinkStackEmpty(s))
	{
		if( ptr)
		{
			Visit(ptr->data );
			Push(s,ptr );
			ptr=ptr->lchild;
		}

		else
		{
			Pop(s, &ptr);
			ptr=ptr->rchild;
		}

	}
	DestroyLinkStack(s);

}



//非递归形式的中序遍历序
// 此方法思路不是太清晰
/*
   void InOrderTraverse2( BiTree root )
   {
   if(!root )
   return ;
   BiTree ptr=root;
   pLinkStack s=InitLinkStack();

   do
   {
   while( ptr )
   {
   Push(s,ptr);
   ptr=ptr->lchild;
   } 
   Pop(s, &ptr);
   Visit(ptr->data) ;
   ptr=ptr->rchild ;
   while( ptr )
   {
   Push(s,ptr);
   ptr=ptr->lchild;
   }


   } while ( ! IsLinkStackEmpty(s) ) ;
   }

*/

void InOrderTraverse2( BiTree root )
{
	if(!root )
		return ;
	BiTree ptr=root;
	pLinkStack s=InitLinkStack();

	while( ptr  || !IsLinkStackEmpty(s) )     
	{
		if( ptr )
		{
			Push(s,ptr) ;
			ptr=ptr->lchild ;
		}
		else 
		{
			Pop(s,&ptr ) ;
			Visit(ptr->data);
			ptr=ptr->rchild;
		}

	}   

	DestroyLinkStack(s);
}
/*
 *非递归形式的计算叶子节点个数(遍历采用非递归中序遍历)
 *
 * */
int CountLeaf2(BiTree root)
{
	if(!root)
		return 0;
	int count=0;
	BiTree ptr=root;
	pLinkStack s=InitLinkStack();
	while(ptr || !IsLinkStackEmpty(s) )
	{
		if(ptr)
		{
			Push(s,ptr);
			ptr=ptr->lchild;
		}

		else
		{
			Pop(s,&ptr);
			if(ptr->lchild==NULL && ptr->rchild==NULL)
			{
				count++;
			}
			ptr=ptr->rchild;
		}

	}
	DestroyLinkStack(s);
	return count;
}
/*
 *计算叶子节点的个数
 *
 * */

int CountLeaf(BiTree root)
{
	BiTree ptr=root;
	if(ptr==NULL)
	{
		return 0;
	}
	else if(ptr->lchild==NULL && ptr->rchild==NULL)
	{
		return 1;
	}
	else
	{
		return CountLeaf(ptr->lchild)+CountLeaf(ptr->rchild);

	}

}





/*
 *统计左右孩子都存在的节点的个数
 *这个方法比较巧妙
 *思想:根节点判断是不是,在递归左右子树
 * */
int CountDoubleson(BiTree root)
{
	BiTree ptr=root;
	int n;
	if(ptr ==NULL)
		return 0;
    if(ptr->lchild && ptr->rchild)
	     n=1; //没有用return 1
	else
		 n=0;
	return CountDoubleson(ptr->lchild)+CountDoubleson(ptr->rchild) +n;

}



/*
 *统计节点的个数
 *
 * */

int CountNodes(BiTree root)
{
	if(root ==NULL)
		return 0;
	else	
		return CountNodes(root->lchild)+CountNodes(root->rchild)+1;
}

BiTree Swap(BiTree root)
{
	if(!root)
		return NULL;
	else
	{
	BiTree ptr=(BiTree) malloc(sizeof(BiTNode)) ;

	ptr->data=root->data;
	ptr->rchild=Swap(root->lchild);
	ptr->lchild=Swap(root->rchild);
	return ptr; //这句必须有,把头指针返回
    }
}


BiTree  CopyBiTree(BiTree input )
{
	BiTree output;
	if(!input)
	{
		output=NULL;
		return output;
	}
	else
	{
		output=(BiTree) malloc(sizeof(BiTNode)) ;
		output->data=input->data;
		output->lchild=CopyBiTree(input->lchild );
		output->rchild=CopyBiTree(input->rchild );
		return output ;
	}
}

bool IsEqualBiTree(BiTree root1,BiTree root2)
{
	if(root1==NULL && root2==NULL)
		return true;
	else
	{
		if( root1 && root2 && root1->data==root2->data)
			return IsEqualBiTree(root1->lchild,root2->lchild) && IsEqualBiTree(root1->rchild ,root2->rchild) ;
		else
			return false;

	}

}

void DisplayBiTree(BiTree root)
{
	if(!root)
		return;
	else
	{
		printf("%c",root->data);
		if(root->lchild!=NULL || root->rchild!=NULL)
		{
			printf("(") ;
			DisplayBiTree(root->lchild) ;
			if(root->rchild !=NULL)
			{
				printf( ",") ;
				DisplayBiTree(root->rchild);
			}

			printf( ") ");
		}
	}
}


/*

//----------------竖向打印二叉树--------------------------------------
void DisplayBiTree(BiTree root,int nLayer)
{
if(root==NULL)
return ;
DisplayBiTree(root->rchild,nLayer+3);
int i;
for(i=0;i<nLayer;i++)
{
printf(" ");

}
printf("%c\n",root->data );
DisplayBiTree(root->lchild,nLayer+3 );


}


void LevelOrderTraverse(BiTree root)  //队列
{
if(!root)
return ;
pLinkQueue q=InitLinkQueue();
EnLinkQueue(q , root);  
while(! IsLinkQueueEmpty(q )  )
{
BiTree ptr ;
DeLinkQueue(q,&ptr );
Visit(ptr->data);

if(ptr->lchild)
EnLinkQueue(q, ptr->lchild );
if(ptr->rchild)
EnLinkQueue(q, ptr->rchild);

}
DestroyLinkQueue(q);
}

*/

int main()
{
	BiTree T=CreateBiTree();
	DisplayBiTree( T );
	//    BiTree T1=CreateBiTree();
//	BiTree T1=CopyBiTree(T) ;
    BiTree T1=Swap(T);
	bool result=IsEqualBiTree(T,T1);
	if( result==0 )
		printf("\nthe two trees are  not equal.\n");
	else
		printf("\nthe two trees are equal.\n ");
	printf("PreOrderTraverse :\n");
	PreOrderTraverse(T);
	printf("\n");
	PreOrderTraverse(T1);
	printf("\n");

	printf("InOrderTraverse :\n");
	InOrderTraverse(T);
	printf("\n");
	InOrderTraverse(T1);
	printf("\n");

	printf("PostOrderTraverse :\n");
	PostOrderTraverse(T);
	printf("\n");
	PostOrderTraverse(T1);
	printf("\n");

	printf("LevelOrderTraverse  :\n");
	LevelOrderTraverse(T);
	printf("\n");

	printf("PreOrderTraverse2 非递归形式的先序遍历:\n");
	PreOrderTraverse2(T);
	printf("\n");


	printf("InOrderTraverse2 非递归形式的中序遍历:\n");
	InOrderTraverse2(T);
	printf("\n");
	DataType x='a';
	BiTree p=SearchBiTree(T,x);
	if(p==NULL)
		printf("don't search the %c \n",x);
	else
		printf("can search the %c\n",p->data) ;
	p=SearchBiTree2(T,x);
	if(p==NULL)
		printf("don't search the %c \n",x);
	else
		printf("can search the %c\n",p->data) ;
	printf("the tree's height : %d\n",TreeHeight(T));
	printf("the tree's height 非递归层次遍历形式 : %d\n",TreeHeight2(T));
	printf("the tree's height 非递归采用用户栈形式 : %d\n",TreeHeight3(T));

	printf("the tree's countleaf:%d\n",CountLeaf(T));
	printf("the tree's countleaf 非递归形式:%d\n",CountLeaf2(T));

	printf("the tree's CountDoubleson :%d\n" ,CountDoubleson(T));
	printf("the tree's Nodes:%d\n",CountNodes(T));
	DestroyBiTree(T);
	return 1;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值