数据结构——二叉树

二叉树

数据结构中有一种数据类型叫做,其中用的较为广泛的莫过于二叉树啦。今天我们来看看二叉树这种独特的数据结构
首先二叉树故名思意每个结点最多有两个孩子。二叉树中又分为满二叉树和完全二叉树。比如下图
在这里插入图片描述
这种树为满二叉树
而完全二叉树:设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
在这里插入图片描述
如上图是一个完全二叉树。

创建二叉树

在这里我们用先序遍历创建二叉树,比如下图这个树
在这里插入图片描述
假设"#"表示孩子为空,则我们知道上图中的树的先序遍历结果为abd##ef##g##ch##i##,遍历结果知道后,我们可以通过一个字符串来创建该树。

二叉树接口

在这里主要给大家介绍以下接口

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
  struct node* left;//左孩子
  struct node* right;//右孩子
  char val;//结点值
}node;
node* creattree(char* str,int* idx)//创建结点
void BinaryTreeDestory(node** root)//二叉树销毁
int BinaryTreeSize(node* root)//树的度
int BinaryTreeLeafSize(node* root)//叶子结点个数
int BinaryTreeLevelKSize(node* root, int k)//第K曾结点个数
node* BinaryTreeFind(node* root, char x)//结点查找
void BinaryTreePrevOrder(node* root)//先序遍历(递归法)
void BinaryTreeInOrder(node* root)//中序遍历(递归法)
void BinaryTreePostOrder(node* root)//后序遍历(递归法)

结点创建

node* creattree(char* str,int* idx)//字符串为先序遍历所得序列,通过数组访问其中数组下标需要用指针
{
  if(str[*idx] != '#')
  {
    //建立根节点
    node* root = (node*)malloc(sizeof(node));
    root->val = str[*idx];//赋值
    ++(*idx);//字符串后移一位
    root->left = creattree(str,idx);//递归创建右孩子
    ++(*idx);//字符串后移一位
    root->right = creattree(str,idx);//递归创建右子树
  }
  else
    return NULL;//若为#则返回空
}

二叉树销毁

void BinaryTreeDestory(node** root)//二级指针销毁根节点
{
  node* cur = *root;
  if(cur)
  {
    BinaryTreeDestory(&cur->left);//递归释放左子树
    BinaryTreeDestory(&cur->right);//递归释放右子树
    free(cur);//释放结点
    *root = NULL;//根节点之空
  }
}

二叉树的度

int BinaryTreeSize(node* root)
{
	if(root==NULL)//判断孩子是否为空
		return 0;
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
	//左右孩子为空则该子树访问完成度为1
}

二叉树的叶子节点

int BinaryTreeLeafSize(node* root)
{
	if(root == NULL)//如果根为空则该树不存在
		return 0;
	if(root->Left == NULL&&root->right == NULL)//如果该节点左右孩子均为空则为叶子节点返回1
		return 1;
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
	//递归遍历左右子树
}

二叉树第K层节点数

这里需要注意,我们要求第K层的结点,则对右子树来说相当于求K-1层结点,所以我们可以通过递归方法求第K层结点

int BinaryTreeLevelKSize(node* root, int k)
{
	if(root == NULL) //如果根节点为空则该树不存在
		return 0;
	if(k==1)//递归到第K层
		return 1;
	retutrn BinaryTreeLevelKSize(root->left,k-1) + BinaryTreeLevelKSize(root->right,k-1);
	//递归求第k层结点个数
}

二叉树结点查询

node* BinaryTreeFind(node* root, char x)
{
	node* ret = NULL; //临时结点
	if(root == NULL)//如果根为空则返回NULL
		return NULL;
	if(root->val == x)//如果要查找的值为根节点的值则直接返回会根节点
		return root;
	ret = BinaryTreeFind(root->left,x);//递归访问左子树
	//需要注意
	if(ret)//先访问左子树则如果找到了则返回ret,如果未找到此时不能直接返回空,因为还需要遍历右子树
		return ret;
	return BinaryTreeFind(root->right,x);//当右子树无论找到与否直接返回ret即可
}

二叉树的先序,中序,后续遍历

这里主要以打印出各节点值来访问,如果读者需要其它用处,则可自行写

//先序
void BinaryTreePrevOrder(node* root)
{
	if(root)
	{
		//先打印结点值,后遍历打印左右子树
		printf("%c ",root->val);
		BinaryTreePrevOrder(root->left);
		BinaryTreePrevOrder(root->right);
	}
}
//中序
void BinaryTreeInOrder(node* root)
{
	if(root)
	{
		//先遍历左子树,再打印结点值,后遍历右子树
		BinaryTreeInOrder(root->left);
		printf("%c ",root->val);
		BinaryTreeInOrder(root->right);
	}
}
//后续
void BinaryTreePostOrder(node* root)
{
	if(root)
	{
		//先遍历左右子树,再打印结点值
		BinaryTreePostOrder(root->left);
		BinaryTreePostOrder(root->right)
		printf("%c ",root->val);
	}
}

当然,二叉树的函数接口远不止这些,还需要大家不断探索,我也不例外,最后感谢阅读,有疑问者欢迎留言评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值