二叉搜索树的删除操作(附例题)

。。。这一部分真心让我懵逼,可能是我太笨的缘故吧。。。。

二叉搜索树的删除操作。。。具体方法要分情况,

1. 若删除的节点没有孩子的时候,直接删除此节点,然后将父节点NULL;

2.若删除的节点有一个孩子的时候,直接将父节点连接到其孩子节点,然后删除此节点。

3.若有两个节点的时候,这时候就要找个节点代替它了,因为二叉搜索树具有左子树比此节点的值都小,右子树比此节点的值大,所以(1)可以找左子树中节点最大的元素,也就是左子树中最右端的元素,(2)也可以找右子树中节点最小的元素,也就是右子树中最左端的节点。让此节点的值等于子树中选出的值,然后删除子树中的节点,因为被删除的节点不是在最右端就是在最左端,所以可知此节点只有一个孩子。。。。然后转到第二种情况。。。

可以看出,这三种情况都需要记住父节点的地址。。。。

然后看浙大数据结构视频这一节视频给出的代码让我好懵逼,好不容易才理解。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef struct tree
{
    int data;
    struct tree *left,*right;
}tree,*Tree;
//创建二叉搜索树;
Tree Create(Tree t,int data)
{
    if(t)
    {
        if(t->data>=data)
            t->left=Create (t->left,data);
        else
            t->right=Create (t->right,data);
    }
    else
    {
        t=(Tree)malloc(sizeof(tree));
        t->data=data;
        t->left=t->right=NULL;
    }
    return t;
}
//先序遍历二叉搜索树;
void Traverse (Tree t)
{
    if(t)
    {
        printf("%d ",t->data);
        Traverse (t->left);
        Traverse (t->right);
    }
}
//找到子树中最小的节点的地址;
Tree FindMin(Tree t)
{
    if(t)
    while (t->left)
    {
        if(t->left)
            t=t->left;
    }
    return t;
}
Tree Delete (Tree t,int data)
{
    //要被删除的节点
    Tree temp=NULL;
    if(!t)
        printf("好像没有此元素呢\n");
    else if(t->data>data)
        t->left=Delete (t->left,data);
    else if(t->data<data)
        t->right=Delete (t->right,data);
    else
    {
        //有两个子节点时
        if(t->left&&t->right)
        {
            temp=FindMin(t->right);
            t->data=temp->data;
            //下面一定是t->data;因为要找到最小元素并删除它...
            t->right=Delete (t->right,t->data);
        }
        else
        {
            //这里挺让人懵逼的,多想想就好了...
            temp=t;
            if(!t->left)
                t=t->right;
            else if(!t->right)
                t=t->left;
            free(temp);
        }
    }
    return t;
}
int main()
{
    Tree t=NULL;
    int n,temp;
    scanf("%d",&n);
    for (int i=0;i<n;i++)
    {
        scanf("%d",&temp);
        t=Create(t,temp);
    }

    scanf("%d",&temp);
    t=Delete (t,temp);
    Traverse (t);
    return 0;
}

例题为Leetcode的 Delete Node in a BST

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

说明: 要求算法时间复杂度为 O(h),h 为树的高度。

示例:

root = [5,3,6,2,4,null,7]
key = 3

    5
   / \
  3   6
 / \   \
2   4   7

给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。

一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。

    5
   / \
  4   6
 /     \
2       7

另一个正确答案是 [5,2,6,null,4,null,7]。

    5
   / \
  2   6
   \   \
    4   7

 这里用的是递归

Java代码:

 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
         if(root==null)
             return root;
        if(root.val<key)
            root.right=deleteNode (root.right,key);
        else if(root.val>key)
            root.left=deleteNode (root.left,key);
        else 
        {
            if(root.left==null||root.right==null)
            {
                if(root.left==null)
                    return root.right;
                else 
                    return root.left;
            }
            else 
            {
                TreeNode t=root.left;
                while (t.right!=null)
                    t=t.right;
                root.val=t.val;
                root.left=deleteNode (root.left,t.val);
            }
        }
        return root;
    }
}

 

 

 

 

 

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值