首页 > 其他分享 >如何用递归实现二叉搜索树的增删改查

如何用递归实现二叉搜索树的增删改查

时间:2024-05-06 22:46:52浏览次数:15  
标签:return data 改查 二叉 TreeLink 增删 NULL root 节点

点击查看代码
/*
* @Author: WangYiMing
* @Date: 2024-04-23 23:37:21
* @LastEditors: WangYiMing
* @LastEditTime: 2024-04-26 18:22:35
*/
#include <stdio.h>
#include <stdlib.h>

/// @brief 二叉树基础结构
typedef struct binary_tree_node
{
    int data;
    struct binary_tree_node *left;
    struct binary_tree_node *right;
} TreeNode, *TreeLink;

#define QUEUE_ARRAY_USER_DATATYPE TreeLink
#include "queue_link.h"

TreeLink Create_Tree_Node(int data);              // 创建一个新的二叉树节点
TreeLink bst_insert(TreeLink root, TreeLink new); // 按BST规定插入新节点
TreeLink bst_find(TreeLink root, int data);       // 查找搜索二叉树(BST)中的树数据
TreeLink bst_remove(TreeLink root, int data);     // 删除二叉搜索树中的节点data

/// @brief 创建一个新的二叉树节点
/// @param data 新节点的数据
/// @return 成功,返回指向新节点的指针。失败,返回 NULL。
TreeLink Create_Tree_Node(int data)
{
    TreeLink new = (TreeLink)calloc(1, sizeof(TreeNode));
    if (new == (TreeLink)NULL)
    {
        perror("calloc");
        return (TreeLink)NULL;
    }

    new->data = data;
    new->left = NULL;
    new->right = NULL;

    return new;
}

/// @brief 按BST规定插入新节点
/// @param root 指向树的根节点的指针
/// @param new 指向需要插入的新根节点的指针
/// @return 成功,返回指向根节点的指针。失败,返回 NULL。
/// @note BST(Binary Search Tree)搜索二叉树。BST规定:在任何子树中,根节点必须大于其左子树中任意的节点,且必须小于其右子树中任意的节点,换句话说必须满足“小(右)--中(根)--大(左)”的逻辑次序。
TreeLink bst_insert(TreeLink root, TreeLink new)
{
    if (root == (TreeLink)NULL)
    {
        return new;
    }

    if (new == (TreeLink)NULL)
    {
        return root;
    }

    if (new->data >= root->data)
    {
        root->right = bst_insert(root->right, new);
    }
    else
    {
        root->left = bst_insert(root->left, new);
    }
    return root;
}

/// @brief 查找搜索二叉树(BST)中的树数据
/// @param root 指向树的根节点的指针
/// @param data 需要查找的节点中的数据
/// @return 成功,返回指向目标节点的指针。失败,返回 NULL。
TreeLink bst_find(TreeLink root, int data)
{
    if (root == (TreeLink)NULL)
    {
        printf("Tree is NULL or data not found!\n");
        return (TreeLink)NULL;
    }

    if (data < root->data)
    {
        return bst_find(root->right, data);
    }
    else if (data > root->data)
    {
        return bst_find(root->left, data);
    }
    else
    {
        return root;
    }
}

/// @brief 删除二叉搜索树中的节点data
/// @param root 指向树的根节点的指针
/// @param data 需要查删除的节点中的数据
/// @return 成功,返回指向树的根节点的指针。失败,返回 NULL。
/// @note 二叉搜索树在删除节点后,仍要满足二叉搜索树“小(右)--中(根)--大(左)”的逻辑次序。
TreeLink bst_remove(TreeLink root, int data)
{
    if (root == (TreeLink)NULL)
    {
        return (TreeLink)NULL;
    }
    else if (root->data > data) // 需要删除的数据比根节点的数据小,则进入左子树中查找
    {
        root->left = bst_remove(root->left, data);
    }
    else if (root->data < data) // 需要删除的数据比根节点的数据大,则进入右子树中查找
    {
        root->right = bst_remove(root->right, data);
    }
    else if (root->data == data) // 需要删除的数据等于根节点的数据
    {
        if (root->left == NULL && root->right == NULL) // 需要删除的数据在叶子节点中,直接删除
        {
            free(root);
            return (TreeLink)NULL;
        }
        else if (root->left != NULL) // 有左子树,寻找左子树中的最大值节点,用其替换根节点并删除该节点。
        {
            TreeLink max = root->left;
            while (max->right != NULL)
            {
                max = max->right;
            }
            root->data = max->data;
            root->left = bst_remove(root->left, max->data);
        }
        else if (root->right != NULL) // 有右子树,寻找右子树中的最小值节点,用其替换根节点并删除该节点。
        {
            TreeLink min = root->right;
            while (min->left != NULL)
            {
                min = min->left;
            }
            root->data = min->data;
            root->right = bst_remove(root->right, min->data);
        }
    }

    return root;

标签:return,data,改查,二叉,TreeLink,增删,NULL,root,节点
From: https://www.cnblogs.com/yixiaohanbing/p/18176104

相关文章

  • 二叉树
    二叉树特点:每个结点最多有两颗子树,并且子树有左右之分。把一个结点拥有的子树的数量称为结点 的度,度为0的结点称为叶子结点,度不为0称为分支结点,树的最大层数称为树的深度性质:1.非空二叉树中的叶子结点数量等于双分支结点数量+12.二叉树的第i层上最多有2^(i-1)(i>=1)......
  • 二叉树进阶:二叉搜索树、平衡二叉树、KD树(实现KNN算法的快速寻找k个邻居)
    二叉搜索树二叉搜索树又称为二叉排序树、二叉查找树。请记住,本篇所介绍的所有树,都是二叉搜索树,也就是说都用到了二分查找的思想。二叉搜索树的特征:每个结点的左结点都小于结点本身,右结点都大于结点本身。用中序遍历来遍历一棵二叉搜索树,结果必然是有序的。时间复杂度很低......
  • 105. 106. 从中序与后序遍历序列构造二叉树
    https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/思路和106.从中序与后序遍历序列构造二叉树相同/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoder......
  • 106. 从中序与后序遍历序列构造二叉树(leetcode)
    https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/要点是明白中序和后序如何构造二叉树的,并且需要理清当前递归函数的语义,不要一开始就陷入细节,而是思考整棵树与其左右子树的关系,语义是:即构造当前节点,给当前节点左右子树赋值,明......
  • 二叉查找树的接口设计
    /***************************************************filename:BianrySearchTree.c*author:[email protected]*date:2024/05/04*brief:二叉查找树的接口设计*note:None**CopyRight(c)[email protected]......
  • 二叉树相关的三个常见算法题
    算法题一//计算一颗二叉树的所有节点的数量intBinaryTree_CountNode(Tnode_t*root){intn1,n2;if(NULL==root){return0;}n1=BinaryTree_CountNode(root->lchild);n2=BinaryTree_CountNode(root->rchild);returnn1+......
  • 二叉树前中后序遍历 迭代法 只需一招!
    核心思想以中序遍历为例在迭代法中我们拿到1节点由于有左孩子我们就会推入2节点,2节点又有左孩子,所以我们推入4,然后弹出2节点,由于这是第二次访问2节点,也就意味着左子树已经去过了,所以推入5节点。那么我们模拟一下栈的变化假设左边为栈顶。1->21->4......
  • 【每日一题】感染二叉树需要的总时间
    2385.感染二叉树需要的总时间给你一棵二叉树的根节点root,二叉树中节点的值互不相同。另给你一个整数start。在第0分钟,感染将会从值为start的节点开始爆发。每分钟,如果节点满足以下全部条件,就会被感染:节点此前还没有感染。节点与一个已感染节点相邻。返回感染......
  • BST二叉查找树的接口设计
    /***********************************************************************************************************设计BST二叉查找树的接口,为了方便对二叉树进行节点的增删,所以采用双向不循环链表实现,每个节点内部都需要*有2个指针,分别指向该节点的左子树(lchild)和右子树......
  • 二叉树笔试题解题思路
    数据结构二叉树笔试题:解题思路:1.判断是否为空树,若为空树,则返回0;2.定义两个指针备份根结点地址,定义两个整型变量a,b并初始化为0,记录左右子树的深度;先对根结点的左子树进行遍历,若根结点的左结点不为NULL,则a++,把根结点的左结点赋值为新的根结点,再进行上述操作,若根结点的左结点......