数据结构——二叉树(BST)的删除


文章目录

  • 数据结构——二叉树(BST)的删除
  • 前言
  • 一、BST删除的几种情况
  • 二、节点删除方法
    • 1.一般方法
    • 2.对1方法的优化
    • 3.懒汉删除(前继和后继)

前言

在学习数据结构的过程中,二叉树的删除无疑是比较复杂的,因此有许多种不同的方式来实现删除操作。下面仅将自己了解的几种方法写出


一、BST删除的几种情况

如果要删除的是树叶,那么可以立即删除,如果有一个儿子,就直接让该节点删除并让儿子占有该位置。关键是有两个孩子的情况:分别有以下几种方法对两个孩子的情况进行实现。

二、节点删除方法

1.一般方法

void remove(const Comparable & x, BinaryNode * & t)
{if(t == nullptr)return;if(x < t->element)remove(x, t->right);else if(t->left != nullptr && t->right != nullptr)//有两个孩子{t->element = findMin(t->right)->element;remove(t->element, t->right);}else{BinaryNode *oldNode = t;t = (t->left != nullptr) ? t->left : t->right;delete oldNode;}
}

上面代码的效率不高,因为它沿着该树进行两趟搜索以查找和删除右子树的最小节点。这也是书上给出的最简单方法。其实还有更易理解而且更粗暴的方式,那就是直接让左子树移动到右子树最左节点的左子树上。然后让右子树变成root,但是这样就会增加树的高度。

2.对1方法的优化

代码如下:

BinaryNode removeMin(BinaryNode * & t) const
{if( t == nullptr){return nullptr;}if(t->left == nullptr){BinaryNode temp = *t;if(t->right != nullptr){*t = *t->right;delete t->right;}elsedelete t;return temp;}return removeMin(t->left);
}
void remove(const Comparable & x, BinaryNode * & t)
{if(t == nullptr)return;if(x < t->element)remove(x, t->right);else if(t->left != nullptr && t->right != nullptr)//有两个孩子{t->element = removeMin(t->right).element;}else{BinaryNode *oldNode = t;t = (t->left != nullptr) ? t->left : t->right;delete oldNode;}
}

这样就通过一个removeMin函数达到只找一趟的效果了。


3.懒汉删除(前继和后继)

其实还提书中还提到了一种懒汉删除的做法,它在node结构题内部新添加了一个用于计算重复次数的count变量 并在tree 添加了theSize 和 delSize变量

bool findMin(BinaryNode *t)  {if (t) {if (findMin(t->left)) return true;if (t->count>0) {min = t;return true;}return findMin(t->right);}return false;
}void insert(const Comparable & x, BinaryNode * & t){if (t == nullptr){++theSize;t = new BinaryNode{ x, nullptr, nullptr };}else if (x<t->element)insert(x, t->left);else if (x>t->element)insert(x, t->right);else ++t->count;
}
void remove(const Comparable & x, BNode * & t){if (t == nullptr)return;if (x<t->element)remove(x, t->left);else if (x>t->element)remove(x, t->right);else if (t->count>0 && --(t->count) == 0 && ++delSize >= --theSize){//若count大于0,则减1;若减1后为0,则delSize加1 theSize减1;//若delSize>=theSize,则执行delete操作deleteNodes(root); //真正的删除操作delSize = 0;       //delSize归零}
}
void deleteNodes(BinaryNode * & t) {if (t == nullptr) return;//空子树,do nothingif (t->count == 0) {//t需要被删除if ((t->left != nullptr) && (t->right != nullptr)) {if (findMin(t->right)) {//t的两个子树均非空,且在它的右子树中找到了"可用"的最小结点,count > 0t->element = min->element;t->count = min->count;min->count = 0;//右子树中的最小结点即将被删除deleteNodes(t->left);deleteNodes(t->right);}else if (findMax(t->left)) {t->element = max->element;t->count = max->count;max->count = 0;deleteNodes(t->left);deleteNodes(t->right);}else //t的右子树中的所有结点的count均为0,则将其置空.makeEmpty(t);}else {BNode *oldnode = t;t = t->left ? t->left : t->right;delete oldnode;oldnode = nullptr;if (t != nullptr) deleteNodes(t);//若新的t非空,继续对它执行删除操作}}else {//t不需要被删除,继续在它的子树中查找deleteNodes(t->left);deleteNodes(t->right);}
}

数据结构——二叉查找树(BST)的删除相关推荐

  1. 二叉查找树BST的删除操作

    二叉查找树BST的删除操作(哈工大版) C++代码 /***** 二叉查找树BST *****/ #include<iostream> using namespace std;struct ...

  2. c# treeview查找并选中节点_最通俗易懂的二叉查找树(BST)详解

    原来来自 呆萌数据结构-06二叉查找树​imoegirl.com 二叉查找树(Binary Search Tree),简写BST,是满足某些条件的特殊二叉树.任何一个节点的左子树上的点,都必须小于当前 ...

  3. 3. 数据结构--二叉树 BST AVL树 Huffman

    数据结构–二叉树 KEY:(不敢相信没有堆-) 二叉树的定义及其主要特征 ☑️ 二叉树的顺序存储结构和链式存储结构实现 二叉树的遍历及应用 二叉排序(查找.检索)树 (BST) 平衡的二叉检索树- A ...

  4. C语言实现二叉查找树的元素删除功能

    接前一篇博文添加二叉查找树的元素删除功能. #include <stdio.h> #include <stdlib.h>//二叉查找树的节点 struct bst_node { ...

  5. Python数据结构11:树的实现,树的应用,前中后序遍历,二叉查找树BST,平衡二叉树AVL树,哈夫曼树和哈夫曼编码

    1.概念 树一种基本的"非线性"数据结构. 相关术语: 节点Node:组成树的基本部分.每个节点具有名称,或"键值",节点还可以保存额外数据项,数据项根据不同的 ...

  6. 数据结构和算法分析学习笔记(三)--二叉查找树的懒惰删除(lazy deletion)

    这次的问题来自<数据结构与算法分析(C++描述)>的习题4.16,如下: -------------------------- 4.16  重做二叉查找树类以实现懒惰删除.注意,这将影响所 ...

  7. 二叉查找树 (BST)| 删除操作

    我们已经讨论了二叉查找树(BST)|搜索及插入操作.在这篇文章中,将讨论删除操作. 当我们删除一个节点时,会出现三种可能性: 1)要删除的节点是叶节点:我们只需要将该节点从树中直接删除即可 2)要删除 ...

  8. 数据结构:二叉查找树 BST 平均查找长度 ASL 的计算

    平均查找长度 ASL(Average Search Length),即平均查找长度,在查找运算中,由于所费时间在关键字的比较上,所以把平均需要和待查找值比较的关键字次数称为平均查找长度. 它的定义是这 ...

  9. 数据结构 - 二叉排序树BST(创建、遍历、删除节点)

    数组与链表区别: 二叉排序树的创建和遍历 代码实现 package tree.binarysorttree;public class BinarySortTreeDemo {public static ...

最新文章

  1. 在RHEL6.6环境下进行LVS-NAT实验(Vmware模式)
  2. 图解HTTP学习笔记
  3. Angular 条件指令 ngIf 的一个例子
  4. ubuntu 12.04 /sbin/ldconfig.real: /usr/local/lib/*.so.8 不是符号连接 解决办法
  5. Linux 驱动开发之内核模块开发(四)—— 符号表的导出
  6. WSGI直观形象的了解一下
  7. linux服务进程文件,[Linux实用命令]-6-服务与进程管理
  8. Faster RCNN 学习笔记
  9. Windows中下载并安装RabbitMQ
  10. Ubuntu16.04下安装NVIDIA显卡驱动
  11. 3D 目标检测综述梳理图解
  12. 航天器轨迹预测——根据速度和位置确定初轨
  13. latex 琐粹记录
  14. [RK3399][Android7.1.1]系统强制App横屏显示
  15. vue 动态面包屑 通过面包屑带参数跨级跳转 面包屑动态标题 多级路由嵌套设置默认页面和隐藏左侧导航栏显示
  16. d3 企业图谱 仿天眼查 企查查
  17. debian linux 7 安装,Debian 7安装设置教程
  18. Win10系统重装过程(一键装机)
  19. CI获取用户真实IP地址
  20. SCRUM团队的三个角色

热门文章

  1. Whale 帷幄 CGO 管鹤荣:SDP尽显场域数据价值
  2. java 图片流 拼接_java 实现图片拼接
  3. python不能输入中文字_Python脚本中无法输入中文解决办法
  4. 华硕z790让独显和集显同时工作
  5. 终端服务器 安装软件,win2003终端服务器安装文件(光盘提取)
  6. 自定义异常,throw,throws和带你去旅行
  7. java常量表达式是什么_Java常量表达式和代码消除
  8. 在线文本翻译能力新增14个直译模型,打造以中文为轴心语言的翻译系统
  9. Xcode之awakeFromNib
  10. CSDN群发私信脚本-java脚本DEMO示例