本文用C语言实现了二叉排序树(也用到了C++中参数引用特性),并在二叉排序树中依次插入了{5,8,2,9,4,3,1,6,7,10},最终生成的二叉树如下图所示。中序遍历该树得到有序序列{1,2,3,4,5,6,7,8,9,10}
本文的核心是二叉排序树的插入,代码如下。
//插入结点
bool insert_Node(BTree &B, int x){
if(B == NULL){//当B为空树
B = creat_Node(x);//直接构造结点,构造结点的函数见最下方完整代码
return true;
}
if(search_Node(B,x)){//如果在树中查找x的结果为true,说明x之前已经插入树中(判断x是否在树中的函数见最下方完整代码)
printf("结点已存在,无需继续插入");
return false;
}
//下面进入递归代码
if(x < B->data)//如果x小于当前结点的值,则将x插入B的左子树中
insert_Node(B->lchild,x);
else//如果x大于当前结点的值,则将x插入B的右子树中
insert_Node(B->rchild,x);
return true;
}
另外还实现了递归求树高、递归求树的叶子结点的操作。二者思路类似,从结点的角度来看,都是将其左右子树特性返回上一层。
//求树中叶子结点的数量
int get_LeavesNumber(BTree B){
if(B == NULL)//如果是空树,则返回0
return 0;
if(is_LeafNode(B))//如果是叶子结点,则返回1(判断是否为叶子结点的函数见完整代码)
return 1;
//如果不是空树,且是非叶子结点,则递归返回左子树的叶子结点数目+右子树的叶子结点数目
return get_LeavesNumber(B->lchild)+get_LeavesNumber(B->rchild);
}
//求树高
int get_TreeHight(BTree B){
if(B == NULL)//遇到空树,返回0
return 0;
if(is_LeafNode(B))//遇到叶子结点,返回高度为1
return 1;
//遇到非叶结点,其左右子树中,高度较大子树的高度+1极为当前树的高度
return (get_TreeHight(B->lchild) > get_TreeHight(B->rchild)?get_TreeHight(B->lchild):get_TreeHight(B->rchild))+1;
}
完整代码如下,运行结果如图
#include <stdio.h>
/*
使用链式存储结构,生成一棵二叉排序树
将数组中的所有元素插入树中,并输出升序序列
*/
//定义树的结点类型
typedef struct BTNode{
int data;
BTNode* lchild;
BTNode* rchild;
}BTNode, *BTree;
//构造结点
BTNode* creat_Node(int x){
BTNode* B = (BTNode*)malloc(sizeof(BTNode));
B->data = x;
B->lchild = NULL;
B->rchild = NULL;
return B;
}
//初始化树
bool init_BTree(BTree &B){
B = NULL;
return true;
}
//查找结点
bool search_Node(BTree B,int x){
if(B == NULL)
return false;
else if(B->data == x)
return true;
else if(x < B->data)
return search_Node(B->lchild,x);
else
return search_Node(B->rchild,x);
}
//插入结点
bool insert_Node(BTree &B, int x){
if(B == NULL){//空树
B = creat_Node(x);
return true;
}
if(search_Node(B,x)){
printf("结点已存在,无需继续插入");
return false;
}
if(x < B->data)
insert_Node(B->lchild,x);
else
insert_Node(B->rchild,x);
return true;
}
//中序遍历并输出
void LDR(BTree B){
if(B != NULL){
LDR(B->lchild);
printf(" %d ",B->data);
LDR(B->rchild);
}
}
//判断是否叶子结点
bool is_LeafNode(BTNode* B){
if(B->lchild == NULL && B->rchild == NULL)
return true;
else
return false;
}
//求树高
int get_TreeHight(BTree B){
if(B == NULL)//遇到空树,返回0
return 0;
if(is_LeafNode(B))//遇到叶子结点,返回高度为1
return 1;
return (get_TreeHight(B->lchild) > get_TreeHight(B->rchild)?get_TreeHight(B->lchild):get_TreeHight(B->rchild))+1;
}
//求树中叶子结点的数量
int get_LeavesNumber(BTree B){
if(B == NULL)
return 0;
if(is_LeafNode(B))
return 1;
return get_LeavesNumber(B->lchild)+get_LeavesNumber(B->rchild);
}
int main()
{
int number_set[10] = {5,8,2,9,4,3,1,6,7,10};
BTree MyBTree;
init_BTree(MyBTree);
for(int i = 0;i < 10;i++){
insert_Node(MyBTree,number_set[i]);
}
LDR(MyBTree);
printf("\nThe hight of this tree is %d.\n",get_TreeHight(MyBTree));
printf("\nThe number of leaves of this tree is %d\n",get_LeavesNumber(MyBTree));
printf("\nExit!\n");
}