有序二叉树,二叉搜索树的实现。完成了二叉树有序插入,节点删除,中序遍历,树高,搜索,删除匹配数据等功能。三个文件,bt.h,bs.cpp,test.cpp.
#ifndef _BT_H_
#define _BT_H_
#include <iostream>
using namespace std;
typedef struct bstreenode{
int data;
struct bstreenode * left;
struct bstreenode * right;
} BSTREE_NODE;
typedef struct bstree{
BSTREE_NODE * root;
int size;
}BSTREE;
//初始化二叉树
void bstree_init(BSTREE * bstree);
//释放
void bstree_deinit(BSTREE * bstree);
//插入
void bstree_insert(BSTREE * bstree,int data);
//删除
bool bstree_erase(BSTREE * bstree,int data);
//删除所有匹配的数据
void bstree_remove(BSTREE * bstree,int data);
//清空
void bstree_clear (BSTREE * bstree);
//更新
void bstree_update(BSTREE * bstree,int _old,int _new);
//判断某个值是否存在
bool bstree_exist(BSTREE * bstree,int data);
//中序遍历
void bstree_traval(BSTREE * bstree);
//获取树的大小
size_t bstree_size(BSTREE * bstree);
//获取树的高度
size_t bstree_height(BSTREE * bstree);
#endif
#include <stdlib.h>
#include "bt.h"
//***************************************************************内部函数*******************************************************************//
//创建节点
static BSTREE_NODE * create_node(int data){
BSTREE_NODE * node = (BSTREE_NODE*)malloc(sizeof(BSTREE_NODE));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
//销毁节点
static void destroy_node(BSTREE_NODE * node){
/*这个函数和下面的函数做比较,为什么同样的指针型参数,这里不用传递二级指针便可以操作实参
解释:我们用malloc函数分配出来的内存并返回一个地址值,而这个地址值就是所分配区域的首地址
而free函数所需要的参数就是malloc出来的地址。这里的形参node的值就是等于传入的实参的,也就是等于
malloc出来的那个值,所以可以实现销毁*/
free (node);
node->left = NULL;
node->right = NULL;
}
/*将node节点插入以root为根的子树中,注意二级指针root,第二个参数接受的是根节点的地址
这里采用二级指针的原因是:我们存在一个二叉树,二叉树的每一个元素都是BSTREE_NODE*/
static void insert(BSTREE_NODE * node,BSTREE_NODE ** root){
/*如果root是空,则直接把这个节点当做树的根节点*/
if (!*root)
*root = node;//这里对node进行了赋值,这是这里要用二级指针的原因
/*如果非空,说明插入的不是根节点,则按照左小右大进行比较插入*/
else if (node)
if (node->data < (*root)->data)
/**/
insert(node,&(*root)->left);
else
insert(node,&(*root)->right);
}
//返回以参数root为根的子树中,数值与参数data匹配的节点的父节点中指向该节点的指针成员变量的地址
//的十分注意本来就是指针型变量的数据
static BSTREE_NODE** find(int data,BSTREE_NODE ** root){
if (!*root)
return root;//查找失败
if (data < (*root)->data)
return find(data,&(*root)->left);
if ((*root)->data < data)
return find(data,&(*root)->right);
return root;
}
//删除以root为根的子树
static void clear (BSTREE_NODE ** root){
if (*root){
clear (&(*root)->left);
clear (&(*root)->right);
destroy_node(*root);
*root = NULL;
}
}
//中序遍历以参数root为根的子树
static void travel(BSTREE_NODE * root){
if (root){
travel(root->left);
printf("%d ",root->data);
travel(root->right);
}
}
//返回以参数root为根的子树的高度
static size_t height (BSTREE_NODE * root){
if (root){
size_t lh = height(root->left);
size_t rh = height(root->right);
return (lh>rh ? lh : rh) + 1;
}
return 0;
}
//**********************************************外部函数*************************************************************************************//
//初始化二叉树
void bstree_init(BSTREE * bstree){
bstree->root = NULL;
bstree->size = 0;
}
//释放
void bstree_deinit(BSTREE * bstree){
clear(&bstree->root);
bstree->size = 0;
}
//插入
void bstree_insert(BSTREE * bstree,int data){
insert(create_node(data),&bstree->root);
bstree->size++;
}
//删除
bool bstree_erase(BSTREE * bstree,int data){
BSTREE_NODE ** node = find(data,&bstree->root);
if (*node){
/*将匹配节点的左子树插入右子树*/
insert((*node)->left,&(*node)->right);
BSTREE_NODE * temp = *node;
/*用匹配节点的右子树的根节点取代匹配节点*/
*node = (*node)->right;
/*销毁匹配节点*/
destroy_node(temp);
bstree->size--;
return true;
}
return false;
}
//删除所有匹配的数据
void bstree_remove(BSTREE * bstree,int data){
while (bstree_erase(bstree,data));
}
//清空
void bstree_clear (BSTREE * bstree){
bstree_deinit(bstree);
}
//更新
void bstree_update(BSTREE * bstree,int _old,int _new){
while (bstree_erase(bstree,_old))
bstree_insert(bstree,_new);
}
//判断某个值是否存在
bool bstree_exist(BSTREE * bstree,int data){
/*对数级时间复杂度*/
return *find(data,&bstree->root) != NULL;
}
//中序遍历
void bstree_traval(BSTREE * bstree){
travel (bstree->root);
printf("\n");
}
//获取树的大小
size_t bstree_size(BSTREE * bstree){
return bstree->size;
}
//获取树的高度
size_t bstree_height(BSTREE * bstree){
return height(bstree->root);
}
#include "bt.h"
#include <time.h>
int main(){
srand(time(NULL));
BSTREE bstree;
bstree_init(&bstree);
for (int i = 0; i < 10;i++){
bstree_insert(&bstree,rand() % 100);
}
bstree_traval(&bstree);
bstree_clear(&bstree);
bstree_insert(&bstree,50);
bstree_insert(&bstree,70);
bstree_insert(&bstree,20);
bstree_insert(&bstree,60);
bstree_insert(&bstree,40);
bstree_insert(&bstree,30);
bstree_insert(&bstree,10);
bstree_insert(&bstree,90);
bstree_insert(&bstree,80);
bstree_traval(&bstree);
printf("大小:%u,树高:%u\n",bstree_size(&bstree),bstree_height(&bstree));
bstree_erase(&bstree,20);
bstree_traval(&bstree);
bstree_insert(&bstree,70);
bstree_insert(&bstree,70);
bstree_traval(&bstree);
bstree_update(&bstree,70,200);
bstree_traval(&bstree);
bstree_remove(&bstree,200);
bstree_traval(&bstree);
bstree_deinit(&bstree);
}