数据结构学习-二叉树的基本操作

数据结构学习-二叉树的基本操作

最近在学习数据结构中的二叉树,想把一些基本操作用C语言实现之后整理一下
主要内容包括

1.二叉树数据结构类型定义:二叉链表
2.按照输入的先序序列建立二叉树,其中#代表空
3.按先序后序中序遍历二叉树(递归)
4.按先序后序中序遍历二叉树(非递归)
5.给定二叉树的后序和中序序列,构造二叉树
6.递归求取二叉树的最大路径和
7.翻转二叉树
8.求二叉树的繁荣度(高度x宽度)

一.二叉树数据结构类型定义:二叉链表
#define ElementType char//元素类型宏定义
typedef struct Bnode//二叉树数据结构类型宏定义:二叉链表
{
	ElementType data;
	struct Bnode *left;
	struct Bnode *right;
	
}BinTree;
typedef Bintree * BT;
二.按照输入的先序序列建立二叉树,其中#代表空

在这里插入图片描述

 BT CreatBinTreeByPreOrder()
 {
 	ElementType ch;
 	BT node;
 	scanf("%c",&ch);
 	if(ch=='#')return 0;
 	else
 	{
 		node=(BT)malloc(sizeof(struct Bnode));
 		node->data=ch;
 		node->left=CreatBinTreeByPreOrder();
 		node->right=CreatBinTreeByPreOrder();
	 }
 	return node;
 	
 }
三.按先序后序中序遍历二叉树(递归)
void InorderTraversal( BT root )
{
	if(!root)return ;
	else
	{
		InorderTraversal(root->left);
		printf("%c",root->data);
		InorderTraversal(root->right);
	}
 } 
void PreorderTraversal( BinTree BT )
{

	if(!root)return ;
	else
	{
		printf("%c",root->data);
		InorderTraversal(root->left);
		InorderTraversal(root->right);
	}

 } 
void PostorderTraversal( BinTree BT )
{
if(!root)return ;
	else
	{
	
		InorderTraversal(root->left);
		InorderTraversal(root->right);
		printf("%c",root->data);
	}

 }  
四.按先序后序中序遍历二叉树(非递归)

这里主要是运用了栈的思想,栈的c语言数据结构定义和基本操作就不列出来了,主要阐述二叉树遍历的算法,而其中的先序和中序遍历相对于后序遍历来说更为简单,故只列出后序遍历的非递归算法

/*后序遍历的非递归算法*/
void PostOrderTravel(BinTree BT)
{
	if(!BT) return;//空树退出 
	Stack S;
	push(S,BT);//根节点入栈 
	while(!IsEmpty(S)||BT)
	{
		if(BT)//从根节点一直向左找,不空就入栈,并标记该节点的右子树未被访问过 
		{
			S->data[S->top].ptr=BT;
			S->data[S->top].tag=0;
			S->top++;
			BT=BT->left;
		}
		else//找到最左端节点后看栈,若栈顶元素有右子树且未被访问,就去访问其右子树并标记访问过,否则退栈输出 
		{
			BT=GetTop(S);//取栈顶结点 
			if(S->data[S->top].tag==0&&BT->right)
			{
				S->data[S->top].tag==1;
				BT=BT->right;
			}
			else 
			{
				printf("%d",S->data[S->top].ptr->data);
				S->top--;
				BT=NULL;
			}
			
		}
		
	}
	
	
	
 } 
五.给定二叉树的后序和中序序列,构造二叉树,其中PS(IS)为子树后序(中序)序列的第一个元素位置 ,PE为最后一个位置
BT CreatBinTree(ElementType Post[],ElementType In[],int PS,int PE,int IS,int IE)
 {
	//如何判断给定序列能否建树?
	if((PE-PS)!=(IE-IS)) 
	return 0;//两序列长度不等不能建树
	ElementType help[PE+1];
	int i,j,flag;
	for(i=0;i<PE+1;i++)//两序列中有字符不相等不能建树 
	help[i]=Post[i];
	for(i=0;i<IE+1;i++) 
	{
		flag=0;
		for(j=0;j<PE+1;j++)
		{
			if(Post[j]==In[i])
			{
			flag=1;break;}
		}
		if(!flag) return 0;//序列不一致 
	}
 	int rlen=0,llen=0;
	 //找到后序序列的最后一个元素 为根
	 BT node=(BT)malloc(sizeof(struct Bnode));
	 node->data=Post[PE];
	 node->left=0;
	 node->right=0;
	  while(In[llen]!=Post[PE])
	  llen++;
	  rlen=IE-llen;
 	if(llen!=0)
 	node->left=CreatBinTree(Post,In,PS,PE-rlen-1,IS,llen-1);
 	if(rlen!=0)
 	node->right=CreatBinTree(Post,In,PE-rlen,PE-1,llen+1,IE);
 	return node;
  } 
六.递归求取二叉树的最大路径和

其中有个自定义max函数需要自己写

int maxPathSum(TreeNodePtr root, int sum) {
if(!root)return 0;
else return root->data+max(maxPathSum(root->left,sum),maxPathSum(root->right,sum));
}
七.翻转二叉树
BT invertTree(BT root) {
if(!root)return NULL;
BT  lefttree=root->left;
root->left=root->right;
root->right=lefttree;
invertTree(root->left);
invertTree(root->right);
return root;
}
八.求二叉树的繁荣度

二叉树的繁荣度定义为二叉树的宽度(所有层中结点最多的层的节点数)乘上二叉树的高度,所以这个函数实现了求二叉树的高度和深度
基本思想是借助队列层序存储二叉树的每个结点,并给每个结点增加一个标记为该节点所在层数nodelev

#define MaxSize 50
#define MaxHeight 10
typedef struct 
{
	BT ptr;
	int nodelev;
}WeightArray;
typedef struct
{
	int rear;
	int front;
	WeightArray a[MaxSize];
}Queue;
int GetFlourishingDegree(BinTree BT)
{
	Queue * Q=(Queue *)malloc(sizeof(Queue));//为队列分配空间
	Q->front=0;
	Q->rear=1;//rear始终指向队列最后一个元素的下一个位置 
	Q->a=(WeightArray *)malloc(MaxSize*sizeof(WeightArray));//为队列中的结构体数组分配空间 
	Q->a[front].ptr=BT;//树根结点入队
	Q->a[front].nodelev=1;//根节点在第一层
	while(front<rear)//当队列不空时
	{
		if(Q->a[front].ptr->left)//左子树进队 
		{
			Q->a[rear].ptr=Q->a[front].ptr->left;
			Q->a[rear].nodelev=Q->a[front].nodelev+1;
			rear++;
		}
		if(Q->a[front].ptr->right)//右子树进队 
		{
			Q->a[rear].ptr=Q->a[front].ptr->right;
			Q->a[rear].nodelev=Q->a[front].nodelev+1;
			rear++;
		}
		front++;//根出队 
	 } 
	int i,height=1,maxlev[MaxHeight],weight=1;
	for(i=0;i<rear;i++)//求树高 
	{
		if(Q->a[i].nodelev>height)
		height=Q->a[i].nodelev;
		maxlev[Q->a[i].nodelev]++;
	}
	for(i=1;i<=height;i++)//求树宽
	{
		if(maxlev[i]>weight)
		weight=maxlev[i];
	}
	
	return height*weight;
}

写在最后

本人大一萌新,初学数据结构与算法,上述代码大部分上机调试过,有什么bug欢迎评论区各路大佬指出。
新人创作实属不易,还请大家不要恶意抄袭,点赞再走,养成习惯,比芯♥

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值