什么是二叉搜索树?
我们把一般的查找操作分为两类,静态查找和动态查找。在静态查找中有一种很快的查找方法(二分查找时间复杂度为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;
}