首页 > 其他分享 >二叉排序树的删除

二叉排序树的删除

时间:2023-11-14 23:35:06浏览次数:37  
标签:lchild BSTNode 删除 二叉 key rchild 排序 data 节点

#include <bits/stdc++.h>

using namespace std;

const int ENDFLAG = -1; //输入结束的标志

typedef struct
{
    int key; //关键字
    int otherinfo; //其他数据项
}ElemType;

istream& operator >>(istream &is, ElemType& e)
{
    cin >> e.key >> e.otherinfo;
    return is;
}

typedef struct BSTNode
{
    ElemType data; //数据域
    struct BSTNode *lchild, *rchild;
}BSTNode, *BSTree;

//当树中不存在关键字等于key的节点时才进行插入
//且新插入的节点一定是一个新添加的叶子节点。
void InsertBST(BSTree &T, ElemType e)
{
    if (T == NULL) //找到插入位置,递归结束
    {
        BSTNode *s = new BSTNode; //生成新的节点*s
        s->data = e; //将新节点的数据域置为e
        s->lchild = s->rchild = NULL; //将新节点的左右子树置为空
        T = s; //把新节点*s连接到已找到的插入位置
    }
    else if (e.key < T->data.key)
        InsertBST(T->lchild, e); //将*s插入左子树
    else
        InsertBST(T->rchild, e); //将*s插入右子树
}

void CreateBST(BSTree &T)
{
    T = NULL;
    ElemType e;
    cin >> e;
    while (e.key != ENDFLAG)
    {
        InsertBST(T, e);
        cin >> e;
    }
}

BSTNode* SearchBST(BSTree T, int key)
{
    if (T == NULL || key == T->data.key) return T; //查找结束,如果失败则返回空指针,成功则返回该指针
    else if (key < T->data.key) return SearchBST(T->lchild, key); //递归查找左子树
    else return SearchBST(T->rchild, key); //递归查找右子树
}

void DeleteBST(BSTree &T, int key)
{
    BSTNode *p = T;
    BSTNode *f = NULL;
    //查找被删节点p及其父节点f
    while (p)
    {
        if (p->data.key == key) break;
        f = p; //*f为*p的父节点
        if (key < p->data.key) p = p->lchild;
        else p = p->rchild;
    }
    if (p == NULL) return; //没找到被删节点,结束
    ///对被删节点p进行处理
    BSTNode *q = p; //将被删节点p用q暂存
    //第一种情况:p的左右子树均不为空
    if ((p->lchild) && (p->rchild))
    {
        //在p的左子树中查找其直接前驱节点,即最右下点
        BSTNode *s = p->lchild;
        while (s->rchild)
        {
            //向右走到尽头
            q = s;
            s = s->rchild;
        }
        p->data = s->data; //将p节点的值改为s节点的值
        //删除s节点
        //注意:因为s为最右下的点,所以s只有左子树
        if (q != p) q->rchild = s->lchild; //q的右子树等于s的左子树
        else q->lchild = s->lchild; //q的左子树等于s的左子树
        delete s;
        return;
    }
    //第二种情况:p的右子树为空。只需重接左子树
    else if (p->rchild == NULL)
    {
        p = p->lchild;
    }
    //第三种情况:p的左子树为空,只需重接右子树
    else if (p->lchild == NULL)
    {
        p = p->rchild;
    }
    //将p所指向的子树挂接到其父节点*f相应的位置上
    if (f == NULL) //被删节点为根节点
        T = p;
    else if (q == f->lchild) //被删节点是父节点的左儿子
        f->lchild = p; //挂接到f的左子树的位置上
    else //被删节点是父节点的右儿子
        f->rchild = p; //挂接到f的右子树的位置上
    delete q;
}

int main()
{
    BSTree T;
    CreateBST(T);
    int x;
    cin >> x;
    printf("要删除的元素是%d\n", x);
    printf("删除%d之前对%d的查询结果如下:\n", x, x);
    BSTNode *s = SearchBST(T, x);
    if (s == NULL) puts("Not Found!");
    else cout << "s->data.key = " << s->data.key << endl;
    DeleteBST(T, x);
    printf("删除%d之后对%d的查询结果如下:\n", x, x);
    s = SearchBST(T, x);
    if (s == NULL) puts("Not Found!");
    else cout << "s->data.key = " << s->data.key << endl;
    return 0;
}

标签:lchild,BSTNode,删除,二叉,key,rchild,排序,data,节点
From: https://www.cnblogs.com/lhycoder/p/BST.html

相关文章

  • (链表)12-单链表的排序
    1importjava.util.*;23/*4*publicclassListNode{5*intval;6*ListNodenext=null;7*publicListNode(intval){8*this.val=val;9*}10*}11*/12publicclassSolution{13/**14*@paramhead......
  • Map遍历删除元素的几种方法
    2哥 :3妹,今天是周末,又不用上班,干嘛看着不开心的样子啊?3妹:你没有看昨天的新闻吗,昨天国家痛失了两位重要人物。2哥:哎,看到了,生老病死,也是没有办法。唯愿逝者安息,生者坚强!我们能做的,就是更加坚强,好好学习,建设祖国!3妹:好吧。2哥:还记得我们之前学习的:list遍历时删除元素的方法 吗,那如......
  • 【笔记】可删除堆
    可删除堆考虑到没什么人会选择手写普通的堆,所以用优先队列实现就好。问题:我们知道,在使用堆或优先队列的时候,我们只能取出堆顶,也就是所维护的最大或最小值。那么如果我们要从所维护的一个元素里删除一个非最大或最小值呢?最暴力的做法是将元素一个一个从堆顶弹出,直到弹出我们要......
  • 任何用let或const声明的属性不能够从它被声明的作用域中删除。任何使用 var 声明的属
    请问以下JS代码的输出结果是什么?leta=1;letobj={x:1}deletea;deleteobj.x;delete2;console.log(a);console.log(obj.x);console.log(2);A1、1、2B1、undefined、2C1、undefined、undefinedDundefined、undefined、undefined正确答案:B需要明确的......
  • k8s 删除Terminating状态的namespace
    查看ns状态root@test-10-5-2-15:~#kubectlgetnsNAMESTATUSAGEcert-managerTerminating19h查看该命名空间下的资源kubectlapi-resources-oname--verbs=list--namespaced|xargs-n1kubectlget--show-kind--ignore-not-found-n......
  • 视频直播点播平台EasyDSS无法删除分组,如何解决?
    EasyDSS视频推拉流平台可支持用户自行上传视频文件,也可将上传的点播文件作为虚拟直播进行播放。平台能支持多屏播放,可兼容Windows、Android、iOS、Mac等操作系统,还能支持CDN转推,具备较强的可拓展性与灵活性。有用户反馈,在EasyDSS上可以创建分组但删除分组时会提示无权操作,求助我们......
  • Python冒泡排序算法
    冒泡排序算法是一种简单的排序算法,其基本思想是通过多次遍历数组,比较相邻的两个元素,如果它们的顺序不对则交换。这样一轮遍历之后,最大(或最小)的元素就会被移动到数组的最后,然后再对剩余的元素进行类似的操作,直到整个数组有序defbubble_sort(arr):n=len(arr)#外层循环控制遍历的......
  • 力扣-34-在排序数组中查找元素的第一个和最后一个位置
    一、题目力扣地址:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/二、解法思路:也是二分查找相关题目,详细解法看注释fromtypingimportListclassSolution:"""leetcode:34二分查找类题目,与传统二分查......
  • 表格数据拖拽排序 sortable.js
    需求拖拽表格的行数据,实现排序。问题拖拽后调用接口,但视图没变,还是原来的顺序场景:拖拽表格行数据后,tableDataArr中数据的orderNum值会改变,实现拖拽换序。期望情况:页面根据更改后的orderNum重新排序。实际情况:接口数据变了,但是页面行数据没有改变。也就是说,页面没有实现......
  • 二叉搜索树的插入 查找 删除
    //1、定义二叉搜索树类,封装查找、插入、删除操作删除最为麻烦,其中对于parent的保存用循环来记录while的条件需多加考虑#include<queue>#include<iostream>usingnamespacestd;classBinaryTreeNode{  private:  intvalue;  BinaryTreeNode*leftChild;......