二叉排序树 C语言实现

基础知识

  • 二叉排序树,又称二叉搜索树(Binary search tree),是一种拥有排序功能的二叉树结构。其特点有:
  1. 结点k的所有左子树结点,都小于等于结点k
  2. 结点k的所有右子树结点,都大于等于结点k
  3. k的子树也都是二叉排序树(递归)

显然,BST的中序遍历输出即为有序递增序列
二叉树的搜索,插入等操作是基于二分法的,所以时间复杂度为logn

  • 二叉树的节点定义
typedef struct BST{
   
   
	int key;
	struct BST *lchild;
	struct BST *rchild;
}BST;

构建BST

创建

利用插入操作进行创建,首个节点在insert中分配,并将它赋值给指针bst,因为在insert中,要改变的是
bst指向的内存的内容,而不改变指针的位置,即将指针传递给函数,并在函数中修改指针的值,所以这里用了二级指针。

//创建 
void create(BST **bst, int *key, int n){
   
   
	int i=0;
	for(i=0; i<n; i++){
   
   
		insert(bst, key[i]);	
	}//这里不需要返回值
}

插入

在插入元素x时,从根节点开始,让x与节点的key比较,如果x < key,则将x递归插入到key 的左子树中,否则将x递归插入到key的右子树中; 如果子树不存在(到了叶节点),则分配内存,并将x放入。

//插入 
int insert(BST **bt, int key){
   
   
	if(*bt == NULL){
   
   
		*bt = (BST*)malloc(sizeof(BST));
		if(*bt == NULL){
   
   
			printf("分配内存失败\n");
			return 0;
		}
		(*bt)->key = key;
		(*bt)->lchild = (*bt)->rchild = NULL;
		return 1;
	}
	if(key == (*bt)->key){
   
   //如果已存在,则插入失败 
		printf("%d已存在!\n", key);
		return 0;
	}
	else if(key < (*bt)->key)
		insert(&(*bt)->lchild, key);
	else
		insert(&(*bt)->rchild, key);	
	return 0;
}

查找

查找元素x,方式为二分查找,从根节点开始,让x与节点的key比较,如果x < key,则在key 的左子树中查找,否则在key的右子树中查找。若找到,返回x对应的指针,否则查找失败

//查找, 返回值是BST指针 
BST *search(BST *bt, int key){
   
   
	if(bt == NULL){
   
   
		printf("查找失败!\n");
		return bt;
	}
	else{
   
   
		if(bt->key == key){
   
   
			return bt;
		}//递归查找
		else if(key < bt->key)
			return search(bt->lchild, key);	
		else
			return search(bt->rchild, key);
	}	 
}

删除节点

删除节点比较复杂,大体分4种情况

  1. 左右子树都为空
    直接清空指针内容即可,*p = NULL;
    在这里插入图片描述
  2. 左子树为空,右子树不为空
    在这里插入图片描述
  3. 右子树为空,左子树不为空
    在这里插入图片描述
  4. 左右子树都不为空
    若将节点p删除,代替它的应该是中序遍历中p的直接前驱s,只需要找到s,将其值赋给p,然后将s删除掉即可,而且对于s,一定符合上面两种情况,删除较容易。
    根据中序遍历规则,s的位置一定是下面两种情况
    在这里插入图片描述
    在这里插入图片描述
    为了便于操作,我们另p为s的父节点。
    (a). q != p在这里插入图片描述
    (b). q == p
    在这里插入图片描述
    代码如下:
//删除节点 
int delnode(BST **p){
   
   
	//删除节点有4种情况
	BST *s, *q;	
	if((*p)->lchild == NULL && (*p)->rchild == NULL){
   
    //左右子树都为空!
		*p = NULL;  //二级指针下,可以直接令*p = NULL 
		return 1; 	
	
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值