二叉排序树

二叉排序树

1.二叉排序树定义

二叉排序树(BST),也称二叉查找树,亦称二叉搜索树。BST是一颗空树,或具有如下性质的非空二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
由此定义可知,BST是一个递归的数据结构,且BST中没有键值相等的节点。如果我们采用中序遍历,即可得到一个键值递增序列

2.二叉排序树查找

步骤:
1)若BST非空,根结点的关键字值等于查找的关键字,成功。
2)查找的关键字值小于根结点的关键字值,递归查左子树。
3)查找的的关键字值根结点的关键字值,递归查右子树。

Node *BST_Search(Node *T,ElemType key,Node *&p){
    //查找函数返回关键词为key的节点指针,如不存在,返回NULL
    p=NULL; //p指向查找节点的双亲,用与查找和删除节点
    while(T!=NULL && T->data!=key){
        p=T;
        if(T->data >key) T=T->lchild;
        else T=T->rchild;
    } 
    return T;
}

3.二叉排序树的插入

BST作为一种动态集合,其特点是结构不是一次生成的,而是在查找过程中,当树中不存在关键字等于给定的节点时进行插入。
步骤:若原BST为空,则直接插入节点,若关键字等于根节点关键字返回插入失败。若关键字小于根节点关键字,则插入左子树中,否则,插入右子树中。

bool BST_Insert(Node *root,ElemType key){
    if(root==NULL){ //原树为空
        root=new Node;
        root->data=key;
        root->lchild=root->rchild=NULL
        return true; 
    }
    else if(key==root->data) return false;
    else if(key<root->data)
       return BST_Insert(root->lchild,key);//插入root的左子树
    else 
       return BST_Insert(root->rchild,key);//插入root的右子树
}

4.二叉排序树的构造

void Creat_BST(Node *root,vector<int> &v){
    root=NULL;
    int len=v.size();
    for(int i=0;i<len;i++){
        BST_Insert(root,v[i]);
    }
}

5.二叉排序树的删除

(1)若待删除节点z是叶子节点,则直接delete
(2)若节点z只有一颗左子树或者右子树,则让z的子树成为父节点的子树,代替z位置
(3)若节点z有左,右子树,令z的直接前驱(或直接后继)替代z,然后再从二叉排序树中删去它的直接前驱(或直接后继),这样转化为第一种情况

*思考:现在我们来想这样一个问题,若在二叉树中删除并插入某节点,得到的二叉树是否和原来相同?

显然,删除节点,既可以删掉叶子节点,也可以删除根节点,还可以删除其他节点,只需要在删除节点后进行适当的调整即可(满足BST定义),而插入节点总是插入叶子位置,因此若在二叉树中删除并插入某节点,再次到的二叉树大多和原来的结构不同

6.代码模块

#include <iostream>
#include<vector>
using namespace std;
#define Element int
struct Node
{
    int data;
    Node *lchild, *rchild;
};

bool BST_Insert(Node * &root,  Element key){
    if(root==NULL) {  // 空树
        root = new Node;
        root->data = key;
        root->lchild = root->rchild = NULL;
        return true;
    }
    if(key == root->data) // BST中不能有相等的值
        return false;
    if(key < root->data) //插左子树 
        return BST_Insert(root->lchild, key);
    return BST_Insert(root->rchild, key); //插右子树 
}

// 建立BST
void CreateBST(Node * &root, vector<int> &v)
{
    root = NULL; 
    for(int i = 0; i <v.size(); i++){
        BST_Insert(root, v[i]);
    }
}

 Node *BST_Search(Node *T,Element key,Node *&p){
    //查找函数返回关键词为key的节点指针,如不存在,返回NULL
    p=NULL; //p指向查找节点的双亲,用与查找和删除节点
    while(T!=NULL && T->data!=key){
        p=T;
        if(T->data >key) T=T->lchild;
        else T=T->rchild;
    } 
    return T;
}

// 中序遍历,可得递增序列 
void InOrder(Node *root){
    Node *T=root;
    if(T){
        InOrder(T->lchild);
        cout << T->data<<" ";
        InOrder(T->rchild);
    }
}

int main(){
    int n;
    cin>>n;
    vector<int>v(n);
    for(int i=0;i<n;i++){
        cin>>v[i];
    }
    Node *T;
    CreateBST(T,v);
    cout<<"输出中序遍历:"<<endl; 
    InOrder(T);
    cout<<endl<<"输出v[0]节点:"<<endl;
    Node *p=BST_Search(T,v[0],p);
    cout<<p->data <<endl;
    cout<<"请输入要插入元素n:"<<endl;
    cin>>n;
    BST_Insert(T,n);
    InOrder(T);
    cout << endl; 
    return 0;
}

测试运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZCAIHUI_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值