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

来源:互联网 发布:linux 安装vncviewer 编辑:程序博客网 时间:2024/05/28 06:04
//BinaryTree.h
#define CHAR//当CHAR定义时,用字符的处理模式//当CHAR没有被定义时,采用整数处理模式#ifdef CHAR//数据类型的定义typedef char DataType;#elsetypedef int Datatype;#endif#define true 1#define false 0typedef 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;elsereturn 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;elsereturn 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) ;elsereturn 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;elsereturn 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 1else n=0;return CountDoubleson(ptr->lchild)+CountDoubleson(ptr->rchild) +n;}/* *统计节点的个数 * * */int CountNodes(BiTree root){if(root ==NULL)return 0;elsereturn 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) ;elsereturn 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");elseprintf("\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);elseprintf("can search the %c\n",p->data) ;p=SearchBiTree2(T,x);if(p==NULL)printf("don't search the %c \n",x);elseprintf("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 0