数据结构 5.5.2章:二叉搜索树的先序建立(附上几个操作)(c语言)

二叉树的先序建立是一种二叉树的构建方式,其优缺点如下:

优点:

  1. 构建简单:二叉树的先序建立方法比较容易理解,只需要按照先序遍历的顺序依次创建每个节点即可。

  2. 时间复杂度低:使用递归的方式进行先序建立二叉树,其时间复杂度为O(n),n为二叉树节点数。

缺点:

  1. 不具有唯一性:由于没有规定左子树和右子树的分界点,不同的节点顺序可能会形成不同的二叉树结构。因此,相同的节点集合,可能有多种不同的二叉树先序遍历序列。

  2. 对于某些特定的二叉树,先序建立可能容易导致树高过高,从而影响操作效率和空间利用率。

综上所述,二叉树的先序建立方法适用于一些简单的二叉树构建,但是由于不具有唯一性以及可能存在树高过高等问题,一般情况下在实际应用中会采用其他更加合适的构建方式。

本代码输入建立二叉树的先序建立棵二叉树,然后执行二叉树复制、求深度、先序、中序和后序遍历操作并输出结果

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h> 

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

void PreCreateBiTree(BiTree *T);
bool isBiTreeEmpty(BiTree T);
void PreOrderTraverse(BiTree T);
void InOrderTraverse(BiTree T);
void PostOrderTraverse(BiTree T);
void Copy(BiTree T, BiTree *NewT);
int Depth(BiTree T);
int NodeCount(BiTree T);
void DestroyBiTree(BiTree T); 

int main(int argc, char *argv[])
{
	BiTree T = NULL;
	printf("请输入二叉树先序节点序列,空位置用'#'代替.\n");
	PreCreateBiTree(&T);
	getchar();
	
	printf("先序遍历: ");
	PreOrderTraverse(T);
	printf("\n");
	
	printf("中序遍历: ");
	InOrderTraverse(T);
	printf("\n");
	
	printf("后序遍历: ");
	PostOrderTraverse(T);
	printf("\n");
	
	printf("树T节点个数为: %d\n", NodeCount(T));
	printf("树T深度为: %d\n", Depth(T));
	
	//复制新树并遍历 
	BiTree NewT = (BiTree)malloc(sizeof(BiTNode));
	Copy(T, &NewT);
	printf("\n");
	printf("NewTree:\n");
	
	printf("先序遍历: ");
	PreOrderTraverse(NewT);
	printf("\n");
	
	printf("中序遍历: ");
	InOrderTraverse(NewT);
	printf("\n");
	
	printf("后序遍历: ");
	PostOrderTraverse(NewT);
	printf("\n"); 
	
	printf("树NewT节点个数为: %d\n", NodeCount(NewT));
	printf("树NewT深度为: %d\n", Depth(NewT));
	//销毁二叉树T和NewT 
	DestroyBiTree(T);
	DestroyBiTree(NewT);
	return 0;
}

//按先序输入建立二叉树(注意双重指针) 
void PreCreateBiTree(BiTree *T)
{
	char ch;
	scanf("%c", &ch);
	if(ch == '#')			//递归结束,建空树 
	{
		*T = NULL;
	}	//of if
	else					//递归建立二叉树 
	{
		*T = (BiTree)malloc(sizeof(BiTNode));	//生成根节点 
		(*T)->data = ch;						//根节点赋值为ch 
		PreCreateBiTree(&((*T)->lchild));		//递归建立左子树 
		PreCreateBiTree(&((*T)->rchild));		//递归建立右子树 
	}	//of else
}	//of PreCreateBiTree()

//二叉树判空
bool isBiTreeEmpty(BiTree T)
{
	if(T == NULL)
	{
		return true;
	}//of if
	return false;
 }// of isBiTreeEmpty()

//先序遍历二叉树
void PreOrderTraverse(BiTree T)
{
	if(isBiTreeEmpty(T))
	{
		return;
	}//of if
	
	printf("%c ", T->data);
	PreOrderTraverse(T->lchild);			//递归遍历左子树
	PreOrderTraverse(T->rchild);			//递归遍历右子树
 } //of PreOrderTraverse()

//中序遍历二叉树
void InOrderTraverse(BiTree T)
{
	if(isBiTreeEmpty(T))
	{
		return;
	}//of if
	
	InOrderTraverse(T->lchild);			//递归遍历左子树
	printf("%c ", T->data);
	InOrderTraverse(T->rchild);			//递归遍历右子树
 } //of InOrderTraverse()
 
//后序遍历二叉树
void PostOrderTraverse(BiTree T)
{
	if(isBiTreeEmpty(T))
	{
		return;
	}//of if
	
	PostOrderTraverse(T->lchild);		//递归遍历左子树 
	PostOrderTraverse(T->rchild);		//递归遍历右子树 
	printf("%c ", T->data);
 } //of PostOrderTraverse()
 
//复制二叉树(注意双重指针)
void Copy(BiTree T, BiTree *NewT)
{
	if(isBiTreeEmpty(T))
	{
		*NewT = NULL;							//如果为空树递归结束 
		return;
	}//of if
	else
	{
		*NewT = (BiTree)malloc(sizeof(BiTNode));
		(*NewT)->data = T->data;				//复制根节点 
		Copy(T->lchild, &((*NewT)->lchild));	//递归复制左子树 
		Copy(T->rchild, &((*NewT)->rchild));	//递归复制右子树 
	}//of else
} 	//of Copy()

//计算二叉树的深度
int Depth(BiTree T)
{
	if(isBiTreeEmpty(T))		//如果为空树,返回深度为0,递归结束 
	{
		return 0;
	}	//of if
	else
	{
		int m = Depth(T->lchild);		//递归计算左子树的深度记为m 
		int n = Depth(T->rchild);		//递归计算右子树的深度记为n 
		return (m > n) ? (m + 1) : (n + 1);		//二叉树的深度为m与n较大者再加1 
	}	//of else
} 	//of Depth()
 
int NodeCount(BiTree T)
{
	if(isBiTreeEmpty(T))			//如果为空树,则节点个数为0,递归结束 
	{
		return 0;
	}	//of if
	else			//否则节点个数为左子树节点数 加 右子树节点数再加 根节点1 
	{
		return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
	}	//of else
}	//of NodeCount()

//销毁二叉树
void DestroyBiTree(BiTree T)
{
	if(!isBiTreeEmpty(T))
	{
		DestroyBiTree(T->lchild);
		DestroyBiTree(T->rchild);
		free(T);
	}	//of if
 } 	//of DestroyBiTree() 

输入先序:ABC##DE#G##F###
运行结果:
在这里插入图片描述
与前一篇文章插入节点操作一样,Copy()函数也需要用到双重指针

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Free Ever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值