数据结构-二叉树

二叉树相关算法

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

#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;
}



你可能感兴趣的:(数据结构,算法,二叉树,遍历)