二叉排序树

1、二叉排序树性质:

1、就是若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
2、若它的右子树不空,则右子树上所有节点的值均大于其根节点的值。
3、换句话说就是:任何节点的键值一定大于其左子树中的每一个节点的键值,并小于其右子树中的每一个节点的键值。

2、二叉排序树查找

要在二叉树中找出查找最大最小元素是极简单的事情,从根节点一直往左走,直到无路可走就可得到最小值;从根节点一直往右走,直到无路可走,就可以得到最大值。

3、二叉排序树插入

插入新元素时,可以从根节点开始,遇键值较大者就向左,遇键值较小者就向右,一直到末端,就是插入点。

int InsertNode(BiNode* &Tree,int k)
{
    if(Tree == nullptr){
        Tree = new BiNode(k);
        return 1;
    }
    else if(k >= Tree->key){
        return InsertNode(Tree->right,k);
    }
    else
        return InsertNode(Tree->left,k);
}

4、二叉排序树删除

对于二叉排序树中的节点A,对它的删除分为两种情况:
1、如果A只有一个子节点,就直接将A的子节点连至A的父节点上,并将A删除; 这里写图片描述
2、如果A有两个子节点,我们就以右子树内的最小节点取代A
这里写图片描述

void DeleteNode(BiNode* &T,int k)
{
    BiNode* p = T;
    if(p == nullptr)
        return;

    if(p->key == k){
        //当前节点是叶子节点
        if(!p->left && !p->right)
            T = nullptr;
        //只有一个左节点
        else if(p->left && !p->right)
            T = p->left;
        //只有一个右节点
        else if(!p->left && p->right)
            T = p->right;
        //左右节点都不空
        else{
            BiNode* s = p->right;
            BiNode* parent = nullptr;
            //没有左孩子
            if(!s->left){
                s->left = p->left;
            }
            else{//有左孩子
                while(s->left){
                    parent = s;
                    s = s->left;
                }
                parent->left = s->right;
                s->left = p->left;
                s->right = p->right;
            }
            T = s;
        }
        delete p;
    }
    else if(T->key > k)
        DeleteNode(T->left,k);
    else
        DeleteNode(T->right,k);
}

完整代码:

#include <iostream>
#include <cstring>

using namespace std;

typedef struct BiNode
{
    int key;
    BiNode* left;
    BiNode* right;

    BiNode(int x): key(x),left(nullptr),right(nullptr){}

};

int InsertNode(BiNode* &Tree,int k)
{
    if(Tree == nullptr){
        Tree = new BiNode(k);
        return 1;
    }
    else if(k >= Tree->key){
        return InsertNode(Tree->right,k);
    }
    else
        return InsertNode(Tree->left,k);
}

BiNode* build(int A[],int len)
{
    BiNode* Tree = nullptr;
    for (int i = 0; i < len; ++i){
        InsertNode(Tree,A[i]);
    }

    return Tree;
}

void visit(BiNode* x)
{

    cout<<x->key<<' ';
}

void preOrder(BiNode* T)
{
    if(T != nullptr){
        visit(T);
        preOrder(T->left);
        preOrder(T->right);
    }

}


void SearchMinNode(BiNode* T)
{
    if(T == nullptr){
        return;
    }
    if(T->left == nullptr)
        visit(T);
    else
        SearchMinNode(T->left);

}

void SearchMaxNode(BiNode* T)
{
    if(T == nullptr)
        return;
    if(T->right == nullptr)
        visit(T);
    else
        SearchMaxNode(T->right);
}

void DeleteNode(BiNode* &T,int k)
{
    BiNode* p = T;
    if(p == nullptr)
        return;

    if(p->key == k){
        //当前节点是叶子节点
        if(!p->left && !p->right)
            T = nullptr;
        //只有一个左节点
        else if(p->left && !p->right)
            T = p->left;
        //只有一个右节点
        else if(!p->left && p->right)
            T = p->right;
        //左右节点都不空
        else{
            BiNode* s = p->right;
            BiNode* parent = nullptr;
            //没有左孩子
            if(!s->left){
                s->left = p->left;
            }
            else{//有左孩子
                while(s->left){
                    parent = s;
                    s = s->left;
                }
                parent->left = s->right;
                s->left = p->left;
                s->right = p->right;
            }
            T = s;
        }
        delete p;
    }
    else if(T->key > k)
        DeleteNode(T->left,k);
    else
        DeleteNode(T->right,k);


}

/*
        50
        / \
       16  56
       /    /
      8     52
*/

int main()
{
    int A[6] = {50,16,56,52,8};
    int len = 5;

    BiNode* Tree = nullptr;
    Tree = build(A,len);

    preOrder(Tree);
    cout<<endl;
    SearchMinNode(Tree);
    cout<<endl;
    SearchMaxNode(Tree);
    cout<<endl;
    DeleteNode(Tree,16);
    cout<<endl;
    preOrder(Tree);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值