【数据结构】二叉搜索树的概念和常见操作

什么是二叉搜索树?

我们把一般的查找操作分为两类,静态查找和动态查找。在静态查找中有一种很快的查找方法(二分查找时间复杂度为O( log(n) )。它之所以可以将时间复杂度降的这么低,是因为在查找之前对数据进行了顺序的排序。在查找时查找的顺序是固定的,是一个判定树一样的结构。把一个线性的查找过程转换成了一个类似树的查找过程。查找效率就是树的高度。从此我们得到启示:在查找时为什么不能把数据直接用二叉树的结构存储。比起线性结构树的动态性更强,它的插入删除操作更加方便。这样就形成了二叉搜索树。
二叉搜索树定义
一颗二叉树,它可以为空,如果不为空,满足下边的性质:
(1)非空左子树的所有节点的值,都小于根节点的值。
(2)非空右子树的所有节点的值,都大于根节点的值。
(3)左右子树都是二叉搜索树。
这样在查找的时候,从根节点找,如果小于去左子树找,如果大于去右子树找。

二叉搜索树的常见操作:

//从二叉搜索树中找到元素data,并返回该节点的地址,如果找不到返回NULL;
Binary_Tree* Find(Binary_Tree* BST,Elementype data)//从搜索二叉树中BST中,找到最小值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Min(Binary_Tree* BST)//从搜索二叉树中BST中,找到最大值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Max(Binary_Tree* BST)
//从二叉搜索树插入一个节点
Binary_Tree* Insert( Binary_Tree* BST, Elementype data )//从二叉搜索树删除一个节点
Binary_Tree* Delete( Binary_Tree* BST, Elementype data )

具体操作:

#include<stdio.h>
#include<stdlib.h>
#define Elementype char
typedef struct Binary_Tree{
	Elementype data;
	struct Binary_Tree* L_child;
	struct Binary_Tree* R_child;
}Binary_Tree;
//从二叉搜索树中找到元素data,并返回该节点的地址,如果找不到返回NULL;
Binary_Tree* Find(Binary_Tree* BST,Elementype data){
	if(BST == NULL){//找不到返回NULL
		return NULL;
	}else if(BST ->data == data){
		return BST;
	}else if(data < BST ->data){
		Find(BST ->L_child,data);
	}else if(data > BST ->data){
		Find(BST ->R_child,data);
	}
}
//从搜索二叉树中BST中,找到最小值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Min(Binary_Tree* BST){
	if(BST == NULL){//树为空
		return NULL;
	}else if(BST ->L_child){
		Find_Min(BST ->L_child);
	}else{
		return BST;
	}
}
//从搜索二叉树中BST中,找到最大值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Max(Binary_Tree* BST){
	if(BST == NULL){//树为空
		return NULL;
	}else if(BST ->R_child){
		Find_Max(BST ->R_child);
	}else{
		return BST;
	}
}
Binary_Tree* Insert( Binary_Tree* BST, Elementype data ){//从二叉搜索树插入一个节点
	if(BST){//树不为空
		if(data < BST ->data){//要插入的值小于该节点的值
			BST ->L_child = Insert(BST ->L_child,data);
		}else if(data > BST ->data){//要插入的值大于该节点的值
			BST ->R_child = Insert(BST ->R_child ,data);
		}
	}else{//树为空
		BST = (Binary_Tree*)malloc(sizeof(Binary_Tree));
		BST ->data = data;
		BST ->L_child = BST ->R_child = NULL;
	}
	return BST;
}
Binary_Tree* Delete( Binary_Tree* BST, Elementype data ){//二叉搜索树删除一个节点
	Binary_Tree* tem = NULL;
	if(BST == NULL){
		printf("删除的节点不在树中");
	}else{
		if(data < BST ->data){
			BST ->L_child = Delete(BST ->L_child,data);
		}else if(data > BST ->data){
			BST ->R_child = Delete(BST ->R_child,data);
		}else{
			if(BST ->L_child && BST ->R_child){//左右子树都存在
				tem = Find_Max(BST ->R_child);//右子树找出最大值节点的地址
				BST ->data = tem ->data;
				Delete(BST ->R_child,tem ->data);//删除右子树的最大值节点;
			}else{
				if(BST ->L_child){
					tem = BST ->L_child;
				}else{
					tem = BST ->R_child;
				}
				free(BST);
				BST = tem;
			}
		}
	}
	return BST;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值