您的位置:首页 > 理论基础 > 数据结构算法

数据结构-二叉树

2015-10-28 22:29 387 查看
二叉树相关算法

主要牵扯遍历,其他都可以通过遍历变形得到。

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: