二叉树
数据结构中有一种数据类型叫做树,其中用的较为广泛的莫过于二叉树啦。今天我们来看看二叉树这种独特的数据结构
首先二叉树故名思意每个结点最多有两个孩子。二叉树中又分为满二叉树和完全二叉树。比如下图
这种树为满二叉树
而完全二叉树:设二叉树的深度为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);
}
}
当然,二叉树的函数接口远不止这些,还需要大家不断探索,我也不例外,最后感谢阅读,有疑问者欢迎留言评论