二叉查找树(BST)

二叉查找树(Binary Search Tree缩写:BST):也称二叉排序树,特征:1)如果左子树不为空,左子树的值小于对应的父节点;2)如果右子树不为空,右子树大于对应的父节点;也就是左<中<右;

插入操作:类似二叉链表,就是在二叉链表的基础上加上判断条件

typedef int dataType;
typedef struct Node
{
    dataType data;
    struct Node *rChild;
    struct Node *lChild;
}BSTNode,*pBST;

//插入节点(pos为根结点指针)
void insertNode(pBST *pos,dataType data)
{
    pBST root = NULL;

    if(*pos == NULL)
    {
        root = (pBST)malloc(sizeof(BSTNode));
        root->data = data;
        root->rChild = NULL;
        root->lChild = NULL;
        *pos = root;
    }
    else if((*pos)->data<data)
    {
        insertNode(&((*pos)->rChild),data);
    }
    else if((*pos)->data>data)
    {
        insertNode(&((*pos)->lChild),data);
    }
}

删除操作: 删除操作分为三种情况:1)待删节点为叶子节点;2)待删节点只有左子树或右子树;3)待删节点有左右子树

对于1):直接删除
对于2):用待删结点的子节点替换
对于3)需要找到待删结点的前驱或者后继节点替换(前驱和后继节点是在中序遍历的基础上说的:中序遍历正好为升序)

对于删除,分别判断使用前驱节点或后继节点替换的情况

typedef int dataType;
typedef struct Node
{
    dataType data;
    struct Node *rChild;
    struct Node *lChild;
}BSTNode,*pBST;

//删除节点
BSTNode * deleteNode(pBST root,dataType data)
{
    BSTNode *pos,*son,*father,*front; //pos:删除的目标节点;son:pos子节点(替换pos);father:pos父节点;front:son的前驱节点
    pos = root;
    father = NULL;
    while(pos)
    {
        if(pos->data == data) break;

        father = pos;
        if(pos->data>data)
        {
            pos = pos->lChild;
        }
        else
        {
            pos = pos->rChild;
        }
    }

    if(pos == NULL)
    {
        return root;
    }
    //使用后继节点替换(后继节点在右子树的最左下角)
    if(pos->lChild == NULL)
    {
        //pos为根节点
        if(father==NULL)
        {
            root = pos->rChild;
        }
        else if(father->lChild == pos)
        {
            father->lChild = pos->rChild;
        }
        else
        {
            father->rChild = pos->rChild;
        }
        free(pos);
    }
    //使用前驱节点替换(前驱节点在左子树的最右下角)
    else
    {
        front = pos;
        son = front->lChild;
        while(son->rChild)
        {
            front = son;
            son = son->rChild;
        }
        if(pos == front)
        {
            front->lChild = son->lChild;
        }
        else
        {
            front->rChild = son->lChild;
        }
        pos->data = son->data;
        free(son);
    }
    return root;
}

测试程序:

#include <iostream>
using namespace std;

typedef int dataType;
typedef struct Node
{
    dataType data;
    struct Node *rChild;
    struct Node *lChild;
}BSTNode,*pBST;

//插入节点(pos为根结点指针)
void insertNode(pBST *pos,dataType data)
{
    pBST root = NULL;

    if(*pos == NULL)
    {
        root = (pBST)malloc(sizeof(BSTNode));
        root->data = data;
        root->rChild = NULL;
        root->lChild = NULL;
        *pos = root;
    }
    else if((*pos)->data<data)
    {
        insertNode(&((*pos)->rChild),data);
    }
    else if((*pos)->data>data)
    {
        insertNode(&((*pos)->lChild),data);
    }
}

//建立二叉搜索树
void createBST(pBST *root)
{
    dataType data;
    *root = NULL;
    cin>>data;
    while(data != -1)
    {
        insertNode(root,data);
        cin>>data;
    }
}

void print(pBST root)
{
    if(root)
    {
        print(root->lChild);
        cout<<root->data<<" ";
        print(root->rChild);
    }
}

//删除节点
BSTNode * deleteNode(pBST root,dataType data)
{
    BSTNode *pos,*son,*father,*front; //pos:删除的目标节点;son:pos子节点(替换pos);father:pos父节点;front:son的前驱节点
    pos = root;
    father = NULL;
    while(pos)
    {
        if(pos->data == data) break;

        father = pos;
        if(pos->data>data)
        {
            pos = pos->lChild;
        }
        else
        {
            pos = pos->rChild;
        }
    }

    if(pos == NULL)
    {
        return root;
    }

    if(pos->lChild == NULL)
    {
        //pos为跟节点
        if(father==NULL)
        {
            root = pos->rChild;
        }
        else if(father->lChild == pos)
        {
            father->lChild = pos->rChild;
        }
        else
        {
            father->rChild = pos->rChild;
        }
        free(pos);
    }

    else
    {
        front = pos;
        son = front->lChild;
        while(son->rChild)
        {
            front = son;
            son = son->rChild;
        }
        if(pos == front)
        {
            front->lChild = son->lChild;
        }
        else
        {
            front->rChild = son->lChild;
        }
        pos->data = son->data;
        free(son);
    }
    return root;
}
BSTNode * findNode(BSTNode * root,dataType data)
{
    BSTNode * pos;
    pos= root;
    while(pos)
    {
        if(pos->data == data) return pos;
        else if(pos->data > data) pos = pos->lChild;
        else pos= pos->rChild;
    }
    return NULL;
}
int main() {

    pBST root;
    cout<<"create BST,please input data:"<<endl;
    createBST(&root);
    print(root);
    cout<<"delete node:"<<endl;
    dataType n;
//    cin>>n;
//    deleteNode(root,n);
//    print(root);
    cout<<"findNode:"<<endl;
    cin>>n;
    cout<<findNode(root,n)->data<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值