二叉搜索树的插入、查找、删除的递归与非递归实现

本文详细介绍了二叉搜索树的特性,并通过递归和非递归方式,分别展示了插入、查找和删除操作的实现过程及测试结果,帮助理解二叉搜索树的操作原理。
摘要由CSDN通过智能技术生成

二叉搜索树:

1、要么为一个空树
2、要么不是一个空树
2.1、如果有左子树,对于该树中的每一个节点来说,该节点的左子树上的所有节点都要比该节点小
2.2、如果有右子树,对于该树中的每一个节点来说,该节点的右子树上的所有节点都要比该节点大

下面我们采用递归方法以及非递归方法来实现一下对于二叉搜索树的插入、查找以及删除操作。
1、基本操作:这里的基本操作思路简单,且在之前的二叉树中详细讲述过,这里就不在过多的赘述,有需要者可以查看之前的文章:
二叉树的基本操作(递归实现前中后序遍历)
二叉树的基本操作(非递归实现前中后序遍历)

//初始化函数
void SearchTreeInit(SearchNode **root)
{
    if(root == NULL)
    {
        //非法输入
        return;
    }
    *root = NULL;
}
//销毁函数
void SearchTreeDestroy(SearchNode **root)
{
    if(root == NULL)
    {
        //非法输入
        return;
    }
    if(*root == NULL)
    {
        //空树
        return;
    }
    //不是空树
    //以后序遍历的顺序递归销毁
    //1、递归销毁左子树
    SearchTreeDestroy(&(*root)->lchild);
    //2、递归销毁右子树
    SearchTreeDestroy(&(*root)->rchild);
    //3、销毁根节点
    DestroyNode(*root);
    *root = NULL;
}

2、插入操作

思路:1、如果我们当前要插入元素的树是一颗空树,那么我们直接将其插入即可。
2、如果不是空树,那么我们就要考虑元素插入以后的树海是不是一棵二叉搜索树。因此我们插入的方法就是:从根节点开始,与根节点的值相比较,如果比根节点的值小,那么就往根节点的左子树插入;如果比根节点的值大,就往根节点的右子树插入,如果相等,我们这里约定该二叉搜索树中不能有重复的元素所以一旦相等就直接插入失败返回。

//插入元素(递归版本)
void SearchTreeInsert(SearchNode **root,DataType to_insert)
{
    if(root == NULL)
    {
        //非法输入
        return;
    }
    if(*root == NULL)
    {
        //空树
        //此时待插入的元素直接插到根节点的位置
        SearchNode *new_node = CreateNode(to_insert);
        *root = new_node;
        return;
    }
    //不是空树
    SearchNode *cur = *root;
    if(to_insert < cur->data)
    {
        //待插入的元素比当前根结点的值小
        //则递归的往左子树插入
        SearchTreeInsert(&cur->lchild,to_insert);
    }
    else if(to_insert > cur->data)
    {
        //待插入的元素比当前根节点的值大
        //则递归的往右子树插入
        SearchTreeInsert(&cur->rchild,to_insert);
    }
    else
    {
        //待插入的元素和当前根节点的值相等
        //我们约定该二叉搜索树中不能有重复的值
        //则直接返回
        return;
    }
}
//测试一下
void TestInsert()
{
    Test_Header;
    SearchNode *root;
    SearchTreeInit(&root);
    SearchTreeInsert(&root,'c');
    SearchTreeInsert(&root,'a');
    SearchTreeInsert(&root,'d');
    SearchTreeInsert(&root,'b');
    SearchTreeInsert(&root,'e');
    printf("先序遍历结果为:");
    SearchTreePreOrder(root);
    printf("\n");
    printf("中序遍历结果为:");
    SearchTreeInOrder(root);
    printf("\n");
}

测试结果如下:
这里写图片描述

//插入(非递归版本)
void SearchTreeInsert1(SearchNode **root,DataType to_insert)
{
    if(root == NULL)
    {
        //非法输入
        return;
    }
    if(*root == NULL)
    {
        //空树
        SearchNode *new_node = CreateNode(to_insert);
        *root = new_node;
        return;
    }
    //不是空树
    //要放置的位置
    SearchNode *cur = *root;
    //新元素的父节点
    SearchNode *pre = NULL;
    //循环找到要插入的位置
    while(1)
    {
        if(cur == NULL)
        {
            //找到了要插入的位置
            //退出循环
            break;
        }
        if(to_insert > cur->data)
        {
            //保存父节点的位置(即当前节点)
            pre = cur;
            //去当前节点的右子树找
            cur = cur->rchild;
        }
        else if(to_insert < cur->data)
        {
            //保存父节点的位置(即当前节点)
            pre = cur;
            //取当前节点的左子树找
            cur = cur
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值