前面一章介绍了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的更多相关文章
-
java二维码之利用谷歌的zxing生成二维码,解析二维码
生成二维码 @RequestMapping("/123") public void test(HttpServletRequest request,HttpServletRespo ...
-
ZXing 生成、解析二维码图片的小示例
概述 ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME ...
-
Java生成、解析二维码
今天遇到需求,使用Java生成二维码图片,网搜之后,大神们早就做过,个人总结一下. 目标:借助Google提供的ZXing Core工具包,使用Java语言实现二维码的生成和解析. 步骤如下: 1.m ...
-
(转)ZXing解析二维码
1 ZXing解析二维码 上一篇文件已经说过如何用ZXing进行生成二维码和带图片的二维码,下面说下如何解析二维码 二维码的解析和生成类似,也可以参考google的一个操作类 BufferedImag ...
-
BST 解析 (一)
这篇博文主要初步介绍Binary Search Tree(BST)的一些基本功能以及应用场景,由于BST的相关知识比较多,下一节会接着补充BST的一些功能.这一节主要分为以下三个要素: BST 的定义 ...
-
JAVA中生成、解析二维码图片的方法
JAVA中生成.解析二维码的方法并不复杂,使用google的zxing包就可以实现.下面的方法包含了生成二维码.在中间附加logo.添加文字功能,并有解析二维码的方法. 一.下载zxing的架包,并导 ...
-
使用zxing生成解析二维码
1. 前言 随着移动互联网的发展,我们经常在火车票.汽车票.快餐店.电影院.团购网站以及移动支付等各个场景下见到二维码的应用,可见二维码以经渗透到人们生活的各个方面.条码.二维码以及RFID被人们应用 ...
-
java生成/解析二维码
package a; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import ...
-
.net Core 调用微信Jsapi接口,H5解析二维码
项目里需要用到扫描二维码,自己实现,不会. 找到了两种解决方案: 通过reqrcode.js,这是一个前端解析二维码内容的js库.如果二维码比较清晰,用这种效果也不错 调用微信扫一扫功能,这种效果很好 ...
-
APS.NET MVC4生成解析二维码简单Demo
一.视图 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewpor ...
随机推荐
-
Codeforces 486E LIS of Sequence --树状数组求LIS
题意: 一个序列可能有多个最长子序列,现在问每个元素是以下三个种类的哪一类: 1.不属于任何一个最长子序列 2.属于其中某些但不是全部最长子序列 3.属于全部最长子序列 解法: 我们先求出dp1[i] ...
-
Hadoop集群管理之配置文件
一.配置文件列表如下: [hadoop@node1 conf]$ pwd /app/hadoop/conf [hadoop@node1 conf]$ echo $HADOOP_HOME /app/ha ...
-
Android 4.0设计规范 优先导读 十大改变
在拜读和翻译了 Android design 设计指导后,对比 Android 4.0 与 Android2.3 及之前版本的 app 设计指导,总结了 Android 4.0 设计的 10 大改变: ...
-
memcached添加IP白名单,只允许指定服务器调用
由于memcached默认安装是不用配置密码的(具体的密码配置我也没怎么研究,据说是有的,大家感兴趣去找一找) 然而memcached链接也是非常简单的 linux命令链接使用 Telnet IP地 ...
-
php中测试运行的时间,从而选择得出优化程序
对于新手来说,优化代码的习惯十分重要, 测试运行的时间,从而得出最好的一个 <?php $t1=microtime(true); //获取程序1,开始的时间 程序1(代码...) $t2=m ...
-
python框架之Flask(1)-Flask初使用
Flask是一个基于 Python 开发并且依赖 jinja2 模板和 Werkzeug WSGI 服务的一个微型框架,对于 Werkzeug 本质是 Socket 服务端,其用于接收 http 请求 ...
-
服务消费和负载(Ribbon)
使用RestTemplate调用服务 在上一篇教程中,我们是这样调用服务的,先通过 LoadBalancerClient 选取出对应的服务,然后使用 RestTemplate 进行远程调用. Load ...
-
MySQL双主.md
MySQL 双主配置 环境说明 系统 IP 主机名 mysql版本 CentOS 6.8 192.168.197.61 C6-node1 5.6.36 CentOS 6.8 192.168.197.6 ...
-
BZOJ 2242 [SDOI2011]计算器 | BSGS
insert的时候忘了取模了-- #include <cstdio> #include <cmath> #include <cstring> #include &l ...
-
Django QuerySet和中介模型
笔记如下 一.QuerySet QuerySet是什么? 类似列表里边存着对象 只和ORM有关系 from app01.models import Book def qDemo(request): b ...