搜索二叉树的创建,插入,查找,删除

二叉搜索树,顾名思义,主要作用为搜索,确定该树中是否存在要搜索的数据。基于找到该数据衍生除了对搜索二叉树的一系列操作,比如插入新数据,删除旧数据等等。

搜索二叉树的性质(设节点为Root)

1)root的左孩子的值永远小于root的值

2)root的右孩子的值永远大于root的值

3)root的左右子树依旧遵循此性质

特点:搜索二叉树不允许一棵树中出现两个相同的数据,(个人看来,为了减少误差,如果出现两个相同的数据,则会有两个地址,大家可以自行思考一下,如果出现这种情况会有什么后果!)

搜索二叉树的创建(也可以称为插入,详细请参考上一篇博客https://blog.csdn.net/xinger_28/article/details/82941358

此博客主要讨论搜索二叉树的查找和删除

查找key:(步骤)

1)如果根节点不空:

         如果根节点Key==查找key,返回key所在节点位置。

        如果根节点Key>查找Key,则在其左子树中找

         如果根节点Key<查找key,则在其右子树中找

2)如果根节点为空,返回NULL

删除key:(步骤)

首先查找元素是否在搜索二叉树中,如果不存在,则返回,否则可以分四种情况删除Key。(已找到root->key==key,root的双亲节点为parent)

1)要判断root为双亲节点的左右孩子,如果为左孩子:

            节点无左孩子,双亲节点的左孩子指向root的右孩子(此时,无需探讨root的右孩子是否为空,若为空,叶子结点)

             节点无右孩子,双亲节点的左孩子指向root的左孩子。

如果右孩子

             节点无左孩子,双亲节点的右孩子指向root的右孩子(此时,无需探讨root的右孩子是否为空,若为空,叶子结点)

             节点无右孩子,双亲节点的右孩子指向root的左孩子。

头文件:二叉搜索树.h

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>


typedef int Key;


typedef struct BSTserchtree{
    Key key;
    struct BSTserchtree*left;
    struct BSTserchtree*right;
}BST;


//创建二叉树,也称为插入
int CreatTree(BST**tree, Key key)
{
    BST*root = *tree; //保存根节点
    BST*parent = NULL;//使双亲节点指向空
    while (root!=NULL)
    {
        if (root->key == key)//搜索二叉树中已经存在key值
        {
            printf("已经存在\n");
            return -1;
        }
        parent = root;//表明root不为空,则存在双亲节点,使parent指向root的双亲节点.
        if (root->key > key)
            root = root->left;//root的值大于key,则key的节点应该存在于root的左子树。
        else
            root = root->right;//root的值小于key,则key的节点应该存在于root的右子树。
    }
    //将值为Key的建立新节点--------插入!
    BST*node = (BST*)malloc(sizeof(BST));
    node->key = key;
    node->left = node->right = NULL;
    //判断根节点是否为空,若为空,将node节点直接付给*tree,使之成为根节点。
    if (parent == NULL)
    {
        *tree = node; //此处注意!!!要用*tree保存node的信息,否则在调用堆栈结束后,无根节点。
        return 0;     //原因在于root为临时变量,此函数一用完将会被销毁,tree中的信息也将会改变
    }
    if (parent->key > key) //找到双亲节点,判断双亲节点值与Key值得大小,确定node应该存在的位置
        parent->left = node;
    else
        parent->right = node;
    return 0;
}

//查找
BST* LOOK(BST*root,Key key)
{
    //BST*root = *tree;
    BST*parent = NULL;
    //查找Key值所在的位置Root,并且找到双亲节点的位置。
    while (root != NULL&&root->key != key)
    {//root不为空,则parent也不为空
        parent = root;
        if (root->key > key)
            root = root->left;
        else
            root = root->right;
    }
    //parent为NULL或者root 为空。根本就不存在节点或者未找到该节点。删除肯定出错!
    if (parent == NULL || root == NULL)
    {
        printf("没找到!\n");
        return NULL;
    }
    return root;
}

//删除
int Delete(BST**tree, Key key)
{
    BST*root = *tree;
    BST*parent = NULL;
    //查找Key值所在的位置Root,并且找到双亲节点的位置。
    while (root != NULL&&root->key != key)
    {//root不为空,则parent也不为空
        parent = root;
        if (root->key > key)
            root = root->left;
        else
            root = root->right;
    }
    //parent为NULL或者root 为空。根本就不存在节点或者未找到该节点。删除肯定出错!
    if (parent == NULL || root == NULL)
    {
        printf("没找到!\n");
        return -1;
    }
    //走到这里,表明root不为空,找到该节点。
    if (parent->left == root){
        if (root->left == NULL)//该节点的左孩子为空,使双亲节点的左孩子指向Root的右孩子
            parent->left = root->right;
        else
            parent->left = root->left;
    }
    else{
        if (root->left == NULL)//该节点的左孩子为空,使双亲节点的右孩子指向Root的右孩子
            parent->right = root->right;
        else
            parent->right = root->left;
    }
    return 0;

}

void  test()
{
    BST*tree = NULL;
    CreatTree(&tree, 5);
    CreatTree(&tree, 4);
    CreatTree(&tree, 3);
    CreatTree(&tree, 8);
    CreatTree(&tree, 6);
    CreatTree(&tree, 10);
    CreatTree(&tree, 7);

    BST*pp=LOOK(tree, 7);

    Delete(&tree, 10);
    Delete(&tree, 11);

}

源文件:test.cpp

#include"二叉搜索树.h"

int main()
{
    test();

    system("pause");
    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值