有关二叉树函数的实现(c语言)

本文详细介绍了二叉树的数据结构定义,包括节点创建、各种遍历方法(前序、中序、后序和层序),以及计算节点总数、叶子节点数、深度、查找特定值、判断是否为完全二叉树和销毁操作。通过实例代码展示了如何实现这些功能。
摘要由CSDN通过智能技术生成

目录

0.二叉树结构定义

1.结点的创建

2函数实现

  2.1前序遍历

2.2中序遍历

2.3后序遍历

2.4层序遍历

3.计算二叉树节点个数

4.计算二叉树叶子节点个数

5.二叉树的深度

6.二叉树查找值为x的节点

7.计算二叉树第k层节点个数

8.判断二叉树是否是完全二叉树

9.二叉树销毁


测试用例树的结构


    BTNode* n1 = BuyBTNode(1);
	BTNode* n2 = BuyBTNode(2);
	BTNode* n3 = BuyBTNode(3);
	BTNode* n4 = BuyBTNode(4);
	BTNode* n5 = BuyBTNode(5);
	BTNode* n6 = BuyBTNode(6);
	BTNode* n7 = BuyBTNode(7);

    n1->left = n2;
	n1->right = n3;
	n2->left = n4;
    n3->left=n5;
	n3->right=n6; 
	n5->left = n7;

0.二叉树结构定义

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType val;
	struct BinaryTreeNode*left;
	struct BinaryTreeNode*right;
}BTNode;

1.结点的创建

//树结点建立
BTNode*BuyBTNode(BTDataType x)
{
	BTNode*p=(BTNode*)malloc(sizeof(BTNode));
	if(p==NULL) 
	{
		perror("malloc fail");
		return NULL;
	} 
	p->val=x;
	p->left=p->right=NULL;
	return p;
}

2函数实现

  2.1前序遍历

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if(root==NULL) return; 
	printf("%d ",root->val);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
}

2.2中序遍历

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
	if(root==NULL) return; 
	BinaryTreeInOrder(root->left);
	printf("%d ",root->val);
	BinaryTreeInOrder(root->right);
}

2.3后序遍历

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
	if(root==NULL) return; 
	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%d ",root->val);
}

2.4层序遍历

关于层序遍历我们可以用队列和数组实现,但本质上还是一样的。区别在于数组是在所有结点存入后一次性输出。

//队列
void QueueBinaryTreeLevelOrder(BTNode* root)
{
    Queue q;//构建栈 
	QueueInit(&q);//初始化栈 
	QueuePush(&q,root);//根结点入栈 
	while(!QueueEmpty(&q))//栈不为空循环 
	{
	  BTNode*p=QueueFront(&q);//记录头节点 
	  QueuePop(&q);//出栈 
	  printf("%d ",p->val);
	  if(p->left) QueuePush(&q,p->left);//左孩子存在入栈 
	  if(p->right) QueuePush(&q,p->right);//右孩子存在入栈
	}
}

3.计算二叉树节点个数

int BinaryTreeSize(BTNode* root)
{
	if(root==NULL) return 0;
	return BinaryTreeSize(root->left)+BinaryTreeSize(root->right)+1;
}

4.计算二叉树叶子节点个数

// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{   
    if(root==NULL) return 0;
    if(root->left==NULL&&root->right==NULL) return 1;
	int l=BinaryTreeLeafSize(root->left);
	int r=BinaryTreeLeafSize(root->right);
	return l+r;
}

5.二叉树的深度

我们可以用递归来求二叉树的深度,求二叉树的深度相当于从根的左子树和右子树中返回最大的深度然后加1求出,求根左子树的深度同样可以这样来求。

//二叉树深度
int BinaryTreeDeep(BTNode* root)
{
	if(root==NULL) return 0;
	int left=BinaryTreeDeep(root->left);//左子树的深度 
	int right=BinaryTreeDeep(root->right);//右子树的深度
	return left>right?left+1:right+1;//返回最大深度+1 
}

我们也可以采用非递归的方式,我们可以借用数组或者队列来解决,原理也是一样的。我们可以层序遍历二叉树,每遍历一层深度就加1。

//非递归
 int QueueBinaryTreeDeep(BTNode* root)
 {
 	BTNode*a[100]={0};
 	int front=0,rear=0,depth=0,level=0;//front指向该层的第一个结点,rear指向最后一个结点的后面 (下一层的第一个) 
 	if(root) a[rear++]=root;//root不为空入数组 
 	level=rear;//level同样指向该层最后一个结点的后面  (下一层的第一个) 
	while(front<rear)
	{   
		if(a[front]->left) a[rear++]=a[front]->left;//左孩子存在入数组 
		if(a[front]->right) a[rear++]=a[front]->right;//右孩子存在入数组 
		front++;//遍历该层下一个结点 
		if(front==level)//此时该层已遍历结束 进入下一层 
		{
			depth++;
			level=rear;
		}
	} 
	return depth;
 }

6.二叉树查找值为x的节点

我们可以采用前序遍历的方式来查找x

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{   
	if(root==NULL) return NULL;
	if(root->val==x) return root;
	BTNode*left=BinaryTreeFind(root->left,x);//遍历左子树找 找到一层一层返回 
	if(left) return left;
	BTNode*right=BinaryTreeFind(root->right,x);
	if(right) return right;
	return NULL;
}

7.计算二叉树第k层节点个数

求第k层的结点个数,可以分为左子树第k层结点的个数+右子树第k层结点的个数。

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if(root==NULL) return 0;
	if(k==1) return 1;
	return BinaryTreeLevelKSize(root->left,k-1)+BinaryTreeLevelKSize(root->right,k-1);
}

8.判断二叉树是否是完全二叉树

我们同样可以采用层序遍历的方式来解决,因为非完全二叉树一层中第一个结点到最后一个结点中间会有空结点。

//判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{
		Queue q;
	QueueInit(&q);
	QueuePush(&q,root);
	while(!QueueEmpty(&q))//队不为空循环 
	{
	  BTNode*p=QueueFront(&q);//取队首元素 
	  if(p==NULL) 
	  {
	  	if(!QueueEmpty(&q)) return 0;//队首元素为空 但队不为空说明不是完全二叉树 
	  }
	  QueuePop(&q);
	  QueuePush(&q,p->left);//左孩子是否为空都入队 
	  QueuePush(&q,p->right);
	}
	return 1;
}

9.二叉树销毁

// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{   
    if(root==NULL) return; 
	BinaryTreeDestory(root->left);
	BinaryTreeDestory(root->right);
	root->val=0;
	root->left=NULL;
	root->right=NULL;
	free(root);
}

小白第一次写博客,关于目录确实不知道怎么搞,还请大佬多多包涵。

文中如有不恰当的地方还请大佬在评论区指出。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值