xdocument查找节点值_二叉查找树(java)

一棵二叉查找树(BST)是一颗二叉树,其中每个节点都含有一个Comparable的键且每个节点的键(以及相关的值)都大于其左子树中的任意节点的键而小于右子树的任意结点的键。

数据表示

和链表一样,我们嵌套定义了一个私有类来表示二叉查找树上的一个节点。每个节点都含有一个键、一个值、一条左链接、一条右链接和一个节点计数器

查找节点

思路:

A、如果二叉查找树为空,查找失败(search miss),返回null;

B、如果根节点的键等于要查找的键,返回根节点的值(search hit)。

C、否则,继续在相应的子树中查找。如果要查找的键小于根节点的键,在左子树中查找;如果要查找的键大于根节点的键,在右子树中查找。

D、重复ABC步骤,直至search miss或者search hit。

插入节点

思路:

A、如果二叉查找树是空的,生成一个新节点,并返回该节点,相当于插入新节点后的二叉树根节点。

B、如果根节点键和要插入的键相等,更新根节点的值。

C、如果要插入的键小于根节点的键,在左子树插入,并将根节点的左链接指向插入后的左子树。

D、如果要插入的键小于根节点的键,在右子树插入,并将根节点的右链接指向插入后的右子树。

E、更新根节点的size,并返回根节点,作为插入新节点后的二叉树根节点。

F、重复ABCD,直至插入或者更新成功。

删除节点

删除节点是二叉搜索树中,最复杂的一种操作,但是也不是特别难,我们分类讨论:

  1. 要删除节点有零个孩子,即叶子节点
6ed2a76595a61bf58a5aad38a8a602a4.png

如图所示,只需要将parent.left设置为null,然后Java垃圾自动回收机制会自动删除current节点。

2.要删除节点有一个孩子

b2801d67a3f0f7d3bbd59c182c74ff3c.png

如图所示,只需要将parent.left设置为curren.right即可。

15ced33c437ade984d8bed61d593661c.gif

3.要删除节点有两个孩子

4d068eb836eafec4875af413aaca38ba.png

这种情况比较复杂,首先我们引入后继节点的概念,如果将一棵二叉树按照中序周游的方式输出,则任一节点的下一个节点就是该节点的后继节点。例如:上图中24的后继节点为26,64的后继节点为70.找到后继节点以后,问题就变得简单了,因为但删除节点有右子树,所以它的后继节点就是右子树中的最小节点。

分为两种情况:

  • 后继节点为待删除节点的右子,只需要将curren用successor替换即可,注意处理好current.left和successor.right.

注意:这种情况下,successor一定没有左孩子,一但它有左孩子,哪它必然不是current的后继节点。

eb7428569bbc414da15d8afc174b1adf.png
24078471ffdee418a4279330cb3f8ac2.gif
  • 后继节点为待删除结点的右孩子的左子树,这种情况稍微复杂点,请看动态图片演示。
1a3a967fc7f934c764803893b493d952.png
abaee58950ed825cdd98d200215a6a7a.gif

删除节点分4步

(1)将只想即将被删除的的节点链接保存为t

(2)将x指向它的后继节点min(t.right)

(3)将x的右链接指向deleteMin(x.right)

(4)将x的左链接设为t.left

实现

package find;public class BST, Value> {    private Node root;    public Value get(Key key) {        return get(root, key);    }    //插入操作    public void put(Key key, Value val) {        root = put(root, key, val);    }    //查询    private Value get(Node x, Key key) {        if (x == null) {            return null;        }        int cmp = key.compareTo(x.key);        if (cmp < 0) {            return get(x.left, key);        } else if (cmp > 0) {            return get(x.right, key);        } else {            return x.val;        }    }    private Node put(Node x, Key key, Value val) {        if (x == null) {            return new Node(key, val, 1);        }        int cmp = key.compareTo(x.key);        if (cmp < 0) {            x.left = put(x.left, key, val);        } else if (cmp > 0) {            x.right = put(x.right, key, val);        } else {            x.val = val;        }        x.N = size(x.left) + size(x.right) + 1;        return x;    }    public int size() {        return size(root);    }    private int size(Node x) {        if (x == null) {            return 0;        } else {            return x.N;        }    }    public Key min() {        return min(root).key;    }    private Node min(Node x) {        if (x.left == null) {            return x;        }        return min(x.left);    }    public Key floor(Key key) {        Node x = floor(root, key);        if (x == null) {            return null;        }        return x.key;    }    private Node floor(Node x, Key key) {        if (x == null) return null;        int cmp = key.compareTo(x.key);        if (cmp == 0) {            return x;        } else if (cmp < 0) {            return floor(x.left, key);        }        Node t = floor(x.right, key);        if (t != null) {            return t;        } else {            return x;        }    }    public void deleteMin() {        root = deleteMin(root);    }    private Node deleteMin(Node x) {        if (x == null) {            return x.right;        }        x.left = deleteMin(x.left);        x.N = size(x.left) + size(x.right) + 1;        return x;    }    public void delete(Key key) {        root = delete(root, key);    }    private Node delete(Node x, Key key) {        if (x == null) {            return null;        }        int cmp = key.compareTo(key);        if (cmp < 0) {            x.left = delete(x.left, key);        } else if (cmp > 0) {            x.right = delete(x.right, key);        } else {            if (x.right == null) {                return x.left;            } else if (x.left == null) {                return x.right;            }            Node t = x;            x = min(t.right);            x.right = deleteMin(t.right);            x.left = t.left;        }        x.N = size(x.left) + size(x.right) + 1;        return x;    }    private class Node {        private Key key;        private Value val;        private Node left, right;        private int N;        public Node(Key key, Value val, int N) {            this.key = key;            this.val = val;            this.N = N;        }    }}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三角形 画_CAD入门基础第3节:直角三角形的圆及如何修剪

这个软件&#xff0c;仔细想想&#xff0c;无非就两个命令&#xff0c;一是直线命令&#xff0c;二&#xff0c;就是圆。直线&#xff0c;无非也就是两种&#xff0c;一&#xff0c;是水平直线和垂直于水平直线的竖线&#xff0c;二&#xff0c;就是各种斜线。第一种直线&#…

【转】系统缓存全解析二:动态缓存(4)-第三方分布式缓存解决方案 Memcache(2)...

缓存系统MemCached的Java客户端优化历程&#xff08;转载自http://code.google.com/p/memcache-client-forjava/。&#xff09;Memcached是一种集中式Cache&#xff0c;支持分布式横向扩展。这里需要解释说明一下&#xff0c;很多开发者觉得Memcached是一种分布式缓存系统&…

windows 10下搭建pyspark与遇到的一些问题的解决方法

目录windows 10 下 搭建 pyspark所需要的工具过程与步骤windows 10 下 搭建 pyspark 所需要的工具 Java JDK 1.8.0 spark-2.2.0-bin-hadoop2.7 hadoop-2.7.3 winutils.exe 还需要有python环境&#xff0c;我用的是Anaconda 3&#xff08;默认你已经装好此环境&#xff09;。…

Linux VNC server 安装配置

1.安装vnc server[rootpxe ~]# yum install tigervnc-server -y2.设置 vnc server 开机启动[rootpxe ~]# chkconfig vncserver on3.修改vncserver 配置文件[rootpxe ~]# vi /etc/sysconfig/vncservers在配置文件后添加以下内容VNCSERVERS"2:root"VNCSERVERARGS[2]&qu…

为什么用python写爬虫_python-做爬虫,如何避免牢狱之灾

随着数据资源的爆炸式增长&#xff0c;网络爬虫的应用场景和商业模式变得更加广泛和多样&#xff0c;网络爬虫技术为数据收集者提供了极大的便利&#xff0c;也给专业网络爬虫公司带来巨大的收益。但是与之相伴的是许多人好奇的一件事——爬虫是否违法&#xff1f; 关于这个问题…

vue跳转页面增加等待_vue跳转页面方法

1. router-link1. 不带参数 //name,path都行, 建议用name // 注意&#xff1a;router-link中链接如果是/开始就是从根路由开始&#xff0c;如果开始不带/&#xff0c;则从当前路由开始。 2.带参数 // params传参数 (类似post)// 路由配置 path: "/home/:id"…

开发HTML5手机游戏的5个注意要点--手机开发前景-- 转

过去2年&#xff0c;我们都见证手机和社交游戏的兴起&#xff1a;两大游戏类型既各自发展&#xff0c;同时也开始互相渗透&#xff0c;融入HTML5技术。 手机社交游戏有自己的用户基础&#xff0c;日益蓬勃发展。 这个新兴游戏类型兼容网页社交游戏和本土应用的优点&#xff0c;…

栈(顺序存储)C++模板实现

#include <iostream> using namespace std;template <typename T> class stack{private:int top; //栈顶指针int maxLen; //栈最大长度T *data; //用数组来创建栈public:stack(int top_ -1 , int maxLen_ 10):top(top_),maxLen(maxLen_){data new T[maxLen]; …

java线程池参数含义

转载自 http://blog.csdn.net/zhouhl_cn/article/details/7392607 感谢分享 项目中开发通常不会直接使用ThreadPoolExecutor&#xff0c;而是通过Executors.newFixedThreadPool()这种简易写法&#xff0c;创建适合自己项目的线程池。但是了解最基本的线程池ThreadPoolExecutor是…

第5章 Python 数字图像处理(DIP) - 图像复原与重建1 - 高斯噪声

本章主要讲图像复原与重建&#xff0c;首先是了解一下各种噪声的特点与模型&#xff0c;还有形成的方法。一些重点的噪声&#xff0c;如高斯噪声&#xff0c;均匀噪声&#xff0c;伽马噪声&#xff0c;指数噪声&#xff0c;还有椒盐噪声等。 本章主要的噪声研究方法主要是加性噪…

十进制 转换 2-10 进制,int的扩展方法

public static int ConvertToBase(this int i, int baseToConvertTo){if (baseToConvertTo < 2 || baseToConvertTo > 10){throw new ArgumentException("无法完成转换" baseToConvertTo.ToString());}int resault 0; //存放结果int iterations 0; //十进…

c语言将一个已知头结点的单链表逆序_C语言实现单链表逆序与逆序输出实例

单链表的逆序输出分为两种情况&#xff0c;一种是只逆序输出&#xff0c;实际上不逆序&#xff1b;另一种是把链表逆序。本文就分别实例讲述一下两种方法。具体如下&#xff1a;1.逆序输出实例代码如下&#xff1a;#include#include#includeusing namespace std;typedef struct…

JavaScript之apply()和call()的区别

我 在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示 例,总算是看的有点眉目了,在这里我做如下笔记,希望和大家分享.. 如有什么不对的或者说法不明确的地方希望读者多多提一些意见,以便共同提高.. 主要我是…

doubango简介

1、doubango官网&#xff1a;http://www.doubango.org/ doubango常用项目国内镜像&#xff08;放在淘宝的svn服务器&#xff09;&#xff0c;目前有4个项目&#xff1a;doubango, idoubs, imsdroid, telepresence。项目的svn地址如下格式http://code.taobao.org/svn/【项目名称…

第5章 Python 数字图像处理(DIP) - 图像复原与重建2 - 瑞利噪声

标题瑞利噪声瑞利噪声 瑞利噪声的PDF为 P(z){2b(z−a)e−(z−a)2/b,z≥a0,z<a(5.4)P(z) \begin{cases} \frac{2}{b}(z-a)e^{-(z-a)^2/b}, & z \ge a \\ 0, & z < a\end{cases} \tag{5.4}P(z){b2​(z−a)e−(z−a)2/b,0,​z≥az<a​(5.4) 均值和方差为 zˉa…

2012暑假计划

挺长时间没有更新博客了&#xff0c;主要是因为这段时间比较忙&#xff0c;学习方面都在学习一些新的知识&#xff0c;感觉没有什么可写的。暑假开始了&#xff0c;极其喜欢自学的我准备度过一个美妙的暑假。 学习计划如下&#xff1a; 1.python的学习。由于在学习Linux编程&am…

调焦后焦实现不同距离成像_如何用手机拍出单反的效果,系列学习(一)AF参数“自动调焦”...

首先我们来了解下AF&#xff0c;AF在照相机中是英文Auto Focus的缩写&#xff0c;自动调焦的意思。因此&#xff0c;AF照相机即是自动调焦照相机的简称。   这种照相机的调焦是利用电子测距器自动进行的。当按下照相机快门按钮时&#xff0c;根据被摄目标的距离&#xff0c;电…

简谈http状态码

200&#xff1a;正常发送信息&#xff1b; 302&#xff1a;请求的网页被转移到一个新的地址&#xff0c;但客户访问仍继续通过原始URL地址&#xff0c;重定向&#xff0c;新的URL会在response中的Location中返回&#xff0c;浏览器将会使用新的URL发出新的Request。 303&#x…

python装饰器函数后执行_Python装饰器限制函数运行时间超时则退出执行

实际项目中会涉及到需要对有些函数的响应时间做一些限制&#xff0c;如果超时就退出函数的执行&#xff0c;停止等待。 可以利用python中的装饰器实现对函数执行时间的控制。 python装饰器简单来说可以在不改变某个函数内部实现和原来调用方式的前提下对该函数增加一些附件的功…

js 数组(Array)

一.数组 稠密数组(非稀疏数组) 稀疏数组 二.数组的添加和删除 我们已经常见过添加数组元素最简单的方法:为新索引赋值;也可以使用push()方法在数组末尾增加一个或者多个元素: a []; a.push("zero"); a.push("one","two"); 可以像删除对象属性一…