一、什么是二叉搜索树
BST中文翻译为:二叉搜索树,或者二叉查找树,或者二叉排序树。
二叉树(binary)是一种特殊的树:二叉树的每个节点最多只能有2个子节点。
给二叉树加一个额外的条件,就可以得到一种被称作二叉搜索树(binary search tree)的特殊二叉树。
二叉搜索树要求:每个节点都不比它左子树的任意元素小,而且不比它的右子树的任意元素大。
(如果我们假设树中没有重复的元素,那么上述要求可以写成:每个节点比它左子树的任意节点大,而且比它右子树的任意节点小)
二叉搜索树的定义
1、要么是一棵空树
2、如果不为空,那么其左子树节点的值都小于根节点的值;右子树节点的值都大于根节点的值
3、其左右子树也是二叉搜索树
BST例子:
二、实现要点
1、实现搜索算法。在搜索元素x的时候,可以将x和根节点比较:
(1)如果x等于根节点,那么找到x,停止搜索 (终止条件)
(2)如果x小于根节点,那么搜索左子树
(3)如果x大于根节点,那么搜索右子树
二叉搜索树所需要进行的操作次数最多与树的深度相等。n个节点的二叉搜索树的深度最多为n,最少为log(n)。
2、删除操作。删除节点后,有时需要进行一定的调整,以恢复二叉搜索树的性质。
(1)叶节点可以直接删除。这样的情况下可直接将相应的指针设置为空,然后free。
(2)删除节点只有一个孩子,就让它的父亲指向它的儿子,然后删除这个节点。
(3)删除节点有两个孩子的情况。用右子树中最小数据点代替删除节点!!!递归删除右子树中那个最小的点。
三、实现代码
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef int KeyType;
typedef struct BSTNode
{
KeyType key;
struct BSTNode *left;
struct BSTNode *right;
}*BSTree;
//初始化。建立一颗空树。T指向该树的根。
BSTree MakeEmpty(BSTree T)
{
if(T != NULL)
{//更加遵循树的递归定义
MakeEmpty(T->left);
MakeEmpty(T->right);
free(T);
}
return NULL;
}
//查找最小元,返回其位置(递归形式)
BSTree FindMin(BSTree T)
{
if(T == NULL)
return NULL;
else if(T->left == NULL)
return T;//终止点即是最小元素
else //一直往左孩子找,直到没有左孩子
return FindMin(T->left);
}
//查找最大元,返回其位置(非递归形式)
BSTree FindMax(BSTree T)
{
if(T != NULL)
while(T->right != NULL)
T = T->right;
return T;
}
//查找具有某个关键值的节点,返回其指针
BSTree Find(BSTree T, KeyType x)
{
if(T == NULL)
return NULL;
if(x < T->key)
return Find(T->left, x);
else if(x > T->key)
return Find(T->right, x);
else
return T;
}
//插入元素。返回指向新树根的指针
BSTree Insert(BSTree T, KeyType x)
{//该插入过程,保证了是建立的二叉搜索树!!!
if(T == NULL)
{//T为空时,就建立新节点
T = (BSTNode*)malloc(sizeof(BSTNode));
T->key = x;
T->left = T->right = NULL;
}
else if(x < T->key)
{//将x递归插入到左子树
T->left = Insert(T->left, x);
}
else if(x > T->key)
{//将x递归插入到右子树
T->right = Insert(T->right, x);
}
//当x = T->key的情况就不用插入
return T;
}
//删除节点。
BSTree Delete(BSTree T, KeyType x)
{
if(T == NULL)
{//空树
cout<<"BST为空,无法删除!"<<endl;
}
else
{
if(x < T->key)//向左子树寻找删除点
T->left = Delete(T->left, x);
else if(x > T->key)//向右子树寻找删除点
T->right = Delete(T->right, x);
else
{//找到删除点
BSTree tempNode;
if(T->left && T->right)
{//所删除节点有两个儿子!!!
tempNode = FindMin(T->right);
//用右子树中最小数据点代替删除节点!!!
T->key = tempNode->key;
//递归删除右子树中那个最小的点
T->right = Delete(T->right, tempNode->key);
}
else
{//所删除节点有一个或零个儿子
tempNode = T;
if(T->left == NULL)//也适用于零个的情况
T = T->right;
else if(T->right == NULL)
T = T->left;
free(tempNode);
}
}
}
return T;
}
//打印排序后的二叉搜索树。中序遍历即可。
void PrintInOrderBST(BSTree T)
{//中序遍历后的二叉搜索树是有序序列!!!
if(T == NULL) return;
PrintInOrderBST(T->left);
cout<<T->key<<endl;
PrintInOrderBST(T->right);
}
void PrintPreOrderBST(BSTree T)
{//先序遍历
if(T == NULL) return;
cout<<T->key<<endl;
PrintPreOrderBST(T->left);
PrintPreOrderBST(T->right);
}
int main()
{
BSTree bst = NULL;
BSTree min;
BSTree max;
//随便插入,元素无先后顺序,插入程序会保证建立二叉搜索树
//但是插入顺序可能会影响BST的结构,比如:
//(1)插入顺序:18,5,101,81,8,2则得到BST(先序遍历):18,5,2,8,101,81
//(2)插入顺序:18,5,81,101,8,2则得到BST(先序遍历):18,5,2,8,81,101
bst = Insert(bst, 18);
bst = Insert(bst, 5);
bst = Insert(bst, 81);
bst = Insert(bst, 101);
bst = Insert(bst, 8);
bst = Insert(bst, 2);
cout<<"中序遍历BST : "<<endl;
PrintInOrderBST(bst);
cout<<"先序遍历BST :"<<endl;
PrintPreOrderBST(bst);
min = FindMin(bst);
max = FindMax(bst);
cout<<"最小元:"<<min->key<<endl;
cout<<"最大元:"<<max->key<<endl;
BSTree Findx = Find(bst, 81);
if(Findx != NULL)
cout<<"查找到的元素为:"<<Findx->key<<endl;
else
cout<<"没有该元素!"<<endl;
Delete(bst, 8);
cout<<"删除元素"<<8<<"后 BST : "<<endl;
PrintInOrderBST(bst);
return 0;
}
结果:
中序遍历BST :
2
5
8
18
81
101
先序遍历BST :
18
5
2
8
81
101
最小元:2
最大元:101
查找到的元素为:81
删除元素8后 BST :
2
5
18
81
101
Process returned 0 (0x0) execution time : 0.143 s
Press any key to continue.