二叉树相关算法
主要牵扯遍历,其他都可以通过遍历变形得到。
#include <stdio.h> #include<stdlib.h> //二叉树 typedef struct Node { int data; Node *lchild,*rchild; } BTNode,*BTTree; //线索二叉树 typedef struct ThreadNode { int data; ThreadNode *lchild,*rchild; int ltag,rtag; } ThreadNode,*ThreadTree; //三叉链表表示二叉树 typedef struct TNode { int data; TNode *lchild,*rchild,*parent; } TNode,*TTree; //二叉平衡树AVL typedef struct AVLNode { int data; AVLNode *lchild,*rchild; int bf; } AVLNode,*AVLTree; //先序创建 void PreCreateBTTree(BTTree&T,char flag) { printf("%c child(-1 EOF):",flag); int n; scanf("%d",&n); if(n==-1)T=NULL; else { T=(BTTree)malloc(sizeof(BTNode)); T->lchild=T->rchild=NULL; T->data=n; PreCreateBTTree(T->lchild,'L'); PreCreateBTTree(T->rchild,'R'); } } //访问 void Visit(BTTree T) { printf("%d ",T->data); } //先序递归 void PreVisit(BTTree T) { if(T) { Visit(T); PreVisit(T->lchild); PreVisit(T->rchild); } } //中序递归 void InOrderVisit(BTTree T) { if(T) { InOrderVisit(T->lchild); Visit(T); InOrderVisit(T->rchild); } } //后序递归 void PostVisit(BTTree T) { if(T) { PostVisit(T->lchild); PostVisit(T->rchild); Visit(T); } } //先序非递归 void NPreVisit(BTTree T) { BTNode* Stack[1000],*p=T;//假设节点数少于1000 int top=0; while(p||top>0) { if(p) { Stack[top++]=p; Visit(p); p=p->lchild; } else { p=Stack[--top]; p=p->rchild; } } } //中序非递归 void NInOrderVisit(BTTree T) { BTNode* Stack[1000],*p=T;//假设节点数少于1000 int top=0; while(p||top>0) { if(p) { Stack[top++]=p; p=p->lchild; } else { p=Stack[--top]; Visit(p); p=p->rchild; } } } //后序非递归 void NPostVisit(BTTree T) { BTNode* Stack[1000],*p=T;//假设节点数少于1000 BTNode* pre=NULL;//刚刚访问过的节点 int top=0; while(p||top>0) { if(p) { Stack[top++]=p; p=p->lchild; } else { p=Stack[--top]; if(p->rchild&&p->rchild!=pre)//右子树存在且不是刚访问的 { Stack[top++]=p; p=p->rchild; } else { Visit(p); pre=p; p=NULL; } } } } //层序遍历 void LevelOrder(BTTree T) { BTNode*Queue[1000];//假设节点数少于1000 int front=0,rear=0; BTNode*p=T; if(p) { Queue[rear++]=p; while(rear>front) { p=Queue[front++]; Visit(p); if(p->lchild)Queue[rear++]=p->lchild; if(p->rchild)Queue[rear++]=p->rchild; } } } //递归计算树高 int Depth1(BTTree T) { if(T==NULL)return 0; else { int L=Depth1(T->lchild); int R=Depth1(T->rchild); return 1+(L>R?L:R); } } //非递归计算树高(利用层序遍历原理——队列) int Depth2(BTTree T) { BTNode*Queue[1000];//假设节点数少于1000 int front=0,rear=0,last=0;//last表示一层最后节点在队列中位置 int h=0; BTNode*p=T,*pre=NULL; if(p) { Queue[rear++]=p; last++; while(rear>front) { p=Queue[front++]; if(p->lchild)Queue[rear++]=p->lchild; if(p->rchild)Queue[rear++]=p->rchild; if(front==last)//p指向该层最后一个节点 { last=rear; h++; } } } return h; } //非递归计算树高(利用后序遍历原理——栈) int Depth3(BTTree T) { //与后序遍历不一样的地方见标号 BTNode* Stack[1000],*p=T;//假设节点数少于1000 BTNode* pre=NULL;//刚刚访问过的节点 int top=0; int h=0,maxh=0;//1 while(p||top>0) { if(p) { h++; if(h>maxh)maxh=h;//2 Stack[top++]=p; p=p->lchild; } else { p=Stack[--top]; if(p->rchild&&p->rchild!=pre)//右子树存在且不是刚访问的 { Stack[top++]=p; p=p->rchild; } else { h--; pre=p; p=NULL; } } } return maxh; } //计算树的宽度-节点最多的一层(层序遍历原理) int Width(BTTree T) { BTNode*Queue[1000];//假设节点数少于1000 int front=0,rear=0; int last=0,width=0; BTNode*p=T; if(p) { Queue[rear++]=p; last++; width=1; while(rear>front) { p=Queue[front++]; if(p->lchild)Queue[rear++]=p->lchild; if(p->rchild)Queue[rear++]=p->rchild; if(front==last) { last=rear; if(rear-front>width) { width=rear-front; } } } } return width; } //统计节点数(或把遍历树的算法中visit换成统计节点数) int Count_All(BTTree T) { if(T==NULL)return 0; else { int L=Count_All(T->lchild); int R=Count_All(T->rchild); return L+R+1; } } //统计度为0节点 int Count_0(BTTree T) { if(T==NULL)return 0; else { if(T->lchild==NULL&&T->rchild==NULL) { return 1; } else { int L=Count_0(T->lchild); int R=Count_0(T->rchild); return L+R; } } } //统计度为1节点 int Count_1(BTTree T) { if(T==NULL)return 0; else { int L=Count_1(T->lchild); int R=Count_1(T->rchild); if((T->lchild==NULL&&T->rchild)||(T->lchild&&T->rchild==NULL)) { return L+R+1; } else { return L+R; } } } //统计度为2节点 int Count_2(BTTree T) { if(T==NULL)return 0; else { int L=Count_2(T->lchild); int R=Count_2(T->rchild); if(T->lchild&&T->rchild) { return L+R+1; } else { return L+R; } } } //交换树的左右子树(后序) void Exchange1(BTTree &T) { if(T) { Exchange1(T->lchild); Exchange1(T->rchild); BTNode*p=T->lchild; T->lchild=T->rchild; T->rchild=p; p=NULL; } } //交换树的左右子树(先序) void Exchange2(BTTree &T) { if(T) { BTNode*p=T->lchild; T->lchild=T->rchild; T->rchild=p; p=NULL; Exchange2(T->lchild); Exchange2(T->rchild); } } //计算树中每个节点深度 void NodeDepth(BTTree T,int d) { if(T) { printf("node %d deep %d\n",T->data,d); NodeDepth(T->lchild,d+1); NodeDepth(T->rchild,d+1); } } //节点值为x的深度(假设仅有1个x) int X_Depth(BTTree T,int x) { if(T==NULL)return 0; else if(T->data==x) return 1; else { int L=X_Depth(T->lchild,x); int R=X_Depth(T->rchild,x); int max=L>R?L:R; return max>0?max+1:0; } } //节点值为X高度(假设仅有1个x) int X_High(BTTree T,int x) { if(T==NULL)return 0; else if(T->data==x)return Depth1(T); else { int L=X_High(T->lchild,x); int R=X_High(T->rchild,x); return L>R?L:R; } } //节点值为x的父节点 int X_Parent(BTTree T,int x) { if(T==NULL)return 0; else { if(T->data==x)return 1; else if(X_Parent(T->lchild,x)||X_Parent(T->rchild,x)) { Visit(T); return 0; } else return 0; } } //访问节点值为x的所有祖先节点 int Visit_AllParent(BTTree T,int x) { if(T==NULL)return 0; else if(T->data==x||Visit_AllParent(T->lchild,x)||Visit_AllParent(T->rchild,x)) { Visit(T); return 1; } else return 0; } //访问离i,j最近的公共祖先节点(i,j互不为祖先) int CommonAnce(BTTree T,int i,int j) { if(T==NULL)return 0; else if(T->data==i||T->data==j)return T->data; else { int L=CommonAnce(T->lchild,i,j); int R=CommonAnce(T->rchild,i,j); if(L+R>=i+j)Visit(T); if(L+R==2*i||L+R==2*j) { return L; } else return L+R; } } //寻找所有的路径之和为sum的路径 int path[1000];//全局数组 void SumPath(BTTree T,int top,int sum) { if(T) { sum-=T->data; path[top++]=T->data; if(sum==0) { for(int i=0;i<top;i++) { printf("%d ",path[i]); } printf("\n"); } else if(sum>0) { SumPath(T->lchild,top,sum); SumPath(T->rchild,top,sum); } } } //删除叶节点 void DelLeaf(BTTree &T,BTNode *pre) { if(T) { if(T->lchild==NULL&&T->rchild==NULL) { if(pre->lchild==T) { pre->lchild=NULL; } else if(pre->rchild==T) { pre->rchild=NULL; } else if(pre==T) { pre=NULL; } free(T); T=NULL; } else { pre=T; DelLeaf(T->lchild,pre); DelLeaf(T->rchild,pre); } } } //带权路径长度 int PathWeightSum(BTTree T,int h) { if(T==NULL)return 0; else { if(T->lchild==NULL&&T->rchild==NULL) { return T->data*h; } else { int L=PathWeightSum(T->lchild,h+1); int R=PathWeightSum(T->rchild,h+1); return L+R; } } } //判断两棵树是否相似 int IsSimilar(BTTree T1,BTTree T2) { if(T1==NULL&&T2==NULL)return 1; else if(T1&&T2) { return IsSimilar(T1->lchild,T2->lchild)&&IsSimilar(T1->rchild,T2->rchild); } else return 0; } //判断是否为二叉排序树 int IsSortTree(BTTree T) { if(T==NULL)return 1; else { if(T->lchild&&T->lchild->data>=T->data)return 0; if(T->rchild&&T->rchild->data<=T->data)return 0; return IsSortTree(T->lchild)&&IsSortTree(T->rchild); } } //二叉排序树的查找——递归(如果不存在,则添加后保证为二叉排序树) BTNode* BST_Search1(BTTree&T,int x,BTNode*&pre) { if(T==NULL) { T=(BTNode*)malloc(sizeof(BTNode)); T->lchild=T->rchild=NULL; T->data=x; if(pre==NULL) return T; if(x<pre->data) pre->lchild=T; else pre->rchild=T; return T; } else { if(T->data==x)return T; else if(x<T->data) { pre=T; return BST_Search1(T->lchild,x,pre); } else { pre=T; return BST_Search1(T->rchild,x,pre); } } } //二叉排序树的查找——非递归(如果不存在,则添加后保证为二叉排序树) BTNode* BST_Search2(BTTree&T,int x,BTNode*&pre) { pre=NULL; BTTree p=T; while(p&&p->data!=x) { pre=p; if(x<p->data)p=p->lchild; else p=p->rchild; } if(p==NULL) { p=(BTNode*)malloc(sizeof(BTNode)); p->lchild=p->rchild=NULL; p->data=x; if(pre==NULL) { T=p;//第一次插入时为根节点 return p; } if(x<pre->data) pre->lchild=p; else pre->rchild=p; return p; } else return p; } //判断是否为满二叉树 int IsFullTree(BTTree T) { BTNode*Queue[1000];//假设节点数少于1000 int front=0,rear=0; int flag=1; if(T) { BTNode *p=T; Queue[rear++]=p; while(front<rear) { p=Queue[front++]; Queue[rear++]=p->lchild; Queue[rear++]=p->rchild; //遇到第一个左右含空的节点 if(p->lchild==NULL||p->rchild==NULL) { break; } } //保留最后2个节点 while(front<rear-2) { p=Queue[front++]; if(p->lchild||p->rchild) { flag=0; break; } } //判断最后两个节点 if(flag&&(Queue[front]==NULL&&Queue[front+1])) { flag=0; } } return flag; } //销毁 void CrashTree(BTTree&T) { if(T) { CrashTree(T->lchild); CrashTree(T->rchild); T->lchild=T->rchild=NULL; free(T); T=NULL; } } int main() { BTTree T=NULL; PreCreateBTTree(T,'L'); //PreVisit(T);puts(""); //NPreVisit(T);puts(""); //InOrderVisit(T);puts(""); //NInOrderVisit(T);puts(""); //Exchange1(T); //PostVisit(T);puts(""); //NPostVisit(T);puts(""); LevelOrder(T);puts(""); //printf("Depth1:%d\n",Depth1(T)); //printf("Depth2:%d\n",Depth2(T)); //printf("Depth3:%d\n",Depth3(T)); //printf("Width:%d\n",Width(T)); //printf("Count_0:%d\n",Count_0(T)); //printf("Count_1:%d\n",Count_1(T)); //printf("Count_2:%d\n",Count_2(T)); //printf("Count_All:%d\n",Count_All(T)); //NodeDepth(T,1); //printf("%d_Depth:%d\n",2,X_Depth(T,2)); //printf("%d_High:%d\n",3,X_High(T,3)); //X_Parent(T,2);puts(""); //Visit_AllParent(T,2);puts(""); //CommonAnce(T,7,5);puts(""); //int top=0,sum=15; //SumPath(T,top,sum); //DelLeaf(T,T); //int h=0;printf("PathWeightSum:%d\n",PathWeightSum(T,h)); //BTTree T1=NULL,T2=NULL; //PreCreateBTTree(T1,'L');PreCreateBTTree(T2,'L'); //printf("IsSimilar:%d\n",IsSimilar(T1,T2)); //CrashTree(T1);puts("T1 crashed!"); //CrashTree(T2);puts("T2 crashed!"); //printf("IsSortTree:%d\n",IsSortTree(T)); //BTTree BST=NULL;BTNode *pre=NULL; //for(int i=0;i<7;i++) //{ // int x; // scanf("%d",&x); // BST_Search2(BST,x,pre); //} //NInOrderVisit(BST);puts(""); //CrashTree(BST);puts("BST crashed!"); printf("IsFullTree:%d\n",IsFullTree(T)); CrashTree(T);puts("T crashed!"); return 0; }