前面一章介绍了BST的结构和一些简单的基本功能,例如:insert,findMin,nextLarger等等。这一节主要讲解一些BST的delete node操作还有BST的height的分析以及一些潜在的问题。即本节主要包括以下2个部分;

1,Analysis of deletion

2,Tree height analysis

一:Node deletion

delete node的过程是需要依靠前一章的知识,需要了解nextLarger的过程和含义。然后在此基础之上,我们可以将删除node分为以下几类:

1)node是BST的leaf,即left child和right child 都为NULL;

2)node含有left subtree,但是没有right subtree;

3) node 含有right subtree, 但是没有left subtree;

4) node 含有right subtree和left subtree;

那么这4中情况下,如何删除相应的node,有什么规定需要遵守呢?如何删除的呢?下面2图分别展示了如何在上面的4中情况下删除相应的node

前三种的情况都比较简单,可以直观的了解。第四中情况,即node包含左右2个subtree的时候,情况就比较复杂了,我在这把流程解释一遍。当node包含左右2个subtree的时候,首先第一步是找到这个node的nextLarger,第二步copy nextLarger的key到node,第三步删除这个nextLarger node。至此删除node的操作结束。其具体的实现代码如下:(每个人的实现过程可能都不一样,仅供参考学习交流)

/*
*Description: search the node's parent node
*
*parameters:
1. key //the value which we want to find within the BST
2. node//the node which we want to find out who is its parent node
*
*return Node
*
*/
Node *BST::searchParent(int key, Node *node){ if (this->root == NULL) {//the BST has not initialzed yet return NULL; }else{ if (node==NULL) {//we have found all the nodes, but no one matches, which means it is not within the BST return NULL; }else if (key == node->getRight()->getKey()||key == node->getLeft()->getKey()) {//we spot on the key, return the node return node; }else if (key < node->getKey()){//the key is smaller than the node, so it is must be in the left subtree. return searchParent(key, node->getLeft()); }else{// the key is bigger than the node, so it is must be in the right subtree. return searchParent(key, node->getRight()); }
}
} /*
*Description: delete a node from BST
*
*
*parameter:
* 1: key//the key that you want to delete
*
* 2:node //the node that we need to delete
*return void
*
*/
void BST::deleteNode(int key, Node *node){ Node *parentNode;
if (node != this->root) {//node is not the root of the BST parentNode = searchParent(node->getKey(), this->root); }else{//the node is the root of BST parentNode = NULL;
} if (node->getLeft() == nullptr && node->getRight() == nullptr) {//The node has not got any leaf if (parentNode->getKey()>node->getKey()) { parentNode->setLeft(NULL);
}else{ parentNode->setRight(NULL);
} delete(node);
node = NULL; }else if (node->getRight() == nullptr){//has left tree if (parentNode->getKey()>node->getKey()) { parentNode->setLeft(node->getLeft());
}else{ parentNode->setRight(node->getLeft());
} delete node;
node= NULL; }else if(node->getLeft() == nullptr){//has right tree if (parentNode->getKey()>node->getKey()) { parentNode->setLeft(node->getRight());
}else{ parentNode->setRight(node->getRight());
} delete node;
node = NULL; }else{//has two subtrees Node *nextLargerNode = findNextLarger(node); int keyValue = nextLargerNode->getKey(); deleteNode(nextLargerNode->getKey(),nextLargerNode); node->setKey(keyValue); } }

二:BST height 分析

根据前面几节的分析,BST 的insert, nextLarger,search,delete的running time = O (h). 那么具体这个h是多少呢?它跟node 的数量有什么关系呢?根据现在所掌握的知识,一个随机任意的BST的h跟node的数量并没有具体的函数关系,但是我们至少可以知道h的范围是多少,即lgN<=h<=N。其原因如下图所示:

根据上图的实例和分析,我们可以很清晰的分辨出h的范围,所以对于一个不加处理随机的BST,它的时间复杂度是:O(lgN)<=running time<=O(N); 很显然我们只希望要lgN, 而不是线性的N; 因为如果是O(N)的话,BST的有些操作甚至效果不过Heap. 上图左边的视图是一个perfectly balanced的BST,它的时间复杂度是O(lgN),这正式我们想要的。上面的右图则是一个完全不平衡的BST,其时间复杂度=O(N),这种情况是我们应该避免的。 所以接下来的问题就是如何判断一个BST是不是平衡的, 如果不是平衡的,我们应该如何将不平衡的BST转化成平衡的BST。那么下一节我将介绍BST的rotation,平衡和AVL Tree。谢谢

BST 解析 (二)height and deletion的更多相关文章

  1. java二维码之利用谷歌的zxing生成二维码,解析二维码

    生成二维码 @RequestMapping("/123") public void test(HttpServletRequest request,HttpServletRespo ...

  2. ZXing 生成、解析二维码图片的小示例

    概述 ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME ...

  3. Java生成、解析二维码

    今天遇到需求,使用Java生成二维码图片,网搜之后,大神们早就做过,个人总结一下. 目标:借助Google提供的ZXing Core工具包,使用Java语言实现二维码的生成和解析. 步骤如下: 1.m ...

  4. (转)ZXing解析二维码

    1 ZXing解析二维码 上一篇文件已经说过如何用ZXing进行生成二维码和带图片的二维码,下面说下如何解析二维码 二维码的解析和生成类似,也可以参考google的一个操作类 BufferedImag ...

  5. BST 解析 (一)

    这篇博文主要初步介绍Binary Search Tree(BST)的一些基本功能以及应用场景,由于BST的相关知识比较多,下一节会接着补充BST的一些功能.这一节主要分为以下三个要素: BST 的定义 ...

  6. JAVA中生成、解析二维码图片的方法

    JAVA中生成.解析二维码的方法并不复杂,使用google的zxing包就可以实现.下面的方法包含了生成二维码.在中间附加logo.添加文字功能,并有解析二维码的方法. 一.下载zxing的架包,并导 ...

  7. 使用zxing生成解析二维码

    1. 前言 随着移动互联网的发展,我们经常在火车票.汽车票.快餐店.电影院.团购网站以及移动支付等各个场景下见到二维码的应用,可见二维码以经渗透到人们生活的各个方面.条码.二维码以及RFID被人们应用 ...

  8. java生成/解析二维码

    package a; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import ...

  9. .net Core 调用微信Jsapi接口,H5解析二维码

    项目里需要用到扫描二维码,自己实现,不会. 找到了两种解决方案: 通过reqrcode.js,这是一个前端解析二维码内容的js库.如果二维码比较清晰,用这种效果也不错 调用微信扫一扫功能,这种效果很好 ...

  10. APS.NET MVC4生成解析二维码简单Demo

    一.视图 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewpor ...

随机推荐

  1. 接口测试思路,jmeter,接口测试流程

    接口测试总结 一:接口测试思想 接口测试:通过向服务器端发送请求,获取响应与预期结果做对比的一种服务端黑盒测试过程. 解释:接口就是将浏览器,客户端,手机端,或者服务器调用另一个服务器的请求抽离出来测 ...

  2. thinkphp3.2开发网页实现第三方登录

    1.在要添加登录的html里添加登录按钮: <a href="{:U('Public/login/',array('type'=>'weixin'))}">< ...

  3. WebService WSDL结构分析

    转载地址:http://blog.csdn.net/sunchaohuang/article/details/3076375      WSDL (Web Services Description L ...

  4. Python基础学习参考(三):内置函数

    一:内置函数 在第一篇文章中,我们简单的认识了一下print()函数和input()函数,也就是输入和输出,这些函数我们可以直接的调用,不要自己定义或者引入什么,对吧?想这样的函数就叫做内置函数.这里 ...

  5. 用git上传本地文件到github

    1.在自己的github账号下新建仓库--------得到github仓库地址 2.本地安装git---在将要克隆的文件夹下 右击点击Git Bash Here 3.输入命令 $ git clone ...

  6. L2-2. 链表去重

    L2-2. 链表去重 时间限制300 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者陈越给定一个带整数键值的单链表L,本题要求你编写程序,删除那些键值的绝对值有重复的 ...

  7. liunx 系统调用 getopt() 函数

    命令行参数解析函数 -- getopt() getopt()函数声明如下: #include <unistd.h>int getopt(int argc, char * const arg ...

  8. JavaScript核心参考

    Array 方法 concat() 把元素衔接到数组中. every() 测试断言函数是否对每个数组元素都为真. filter() 返回满足断言函数的数组元素. forEach() 为数组的每一个元素 ...

  9. day2--SecureCRT的配置

    生产中,我们是看不到虚拟机的工作界面,虚拟机的界面相当于机房显示屏的样子,实际上我们是在操作工具里面进行管理,这里使用SecureCRT远程连接虚拟机,SecureCRT的设置如下: 1.打开Secu ...

  10. Hibernate开发文档

    hibernate配置 映射约束文件 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3. ...