//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; }
二叉树的各种操作的(递归非递归)的实现,如(递归非递归)先序后序中序层次遍历 二叉树的高度 叶子节点数,所有节点数
最新推荐文章于 2020-05-17 23:54:59 发布