有序二叉树的实现

有序二叉树,二叉搜索树的实现。完成了二叉树有序插入,节点删除,中序遍历,树高,搜索,删除匹配数据等功能。三个文件,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);
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值