树---Binary Search Tree(二叉搜索树BST)

一、什么是二叉搜索树

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.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值