Java TreeMap异常值问题?

本帖最后由 司懿卓 于 19:13 编辑
上面的需求是对Student对象进行自定排序.
并且使用了两种Map集合输出方式.
但是,再加入匿名内部比较器后,第一种方法的addr无法正常输出.
取消比较器. 输出正常.
这昰不使用比较器的输出结果:

这是使用比较器的输出结果:


谢谢帮忙解决问题的朋友..  还是自己的问题,在做其他练习,就想着等这个解决.  这是我的錯.

public get( key)返回指定键所映射的值如果对于该键而言,此映射不包含任何映射关系则返回 null。 更确切地讲如果此映射包含从键 k 到值 v 的映射关系,根据该映射的排序 key 比较起来等于 k那么此方法将返回 v;否则返回 null。(最多只能有一个这样的映射关系)

TreeMap使用红黑树存储元素可以保证え素按key值的大小进行遍历。

SortedMap规定了元素可以按key的大小来遍历它定义了一些返回部分map的方法。

// 返回fromKey(包含)到toKey(不包含)之间的元素组成嘚子map * 使用传入map的比较器并把传入map中的所有元素保存到新的TreeMap中

获取元素,典型的二叉查找树的查找方法


我是一条美丽的分割线,前方高能请做好准备。


(1)每个节点或者是黑色或者是红色。

(3)每个叶子节点(NIL)是黑色(注意:这里叶子节点,是指为空(NIL或NULL)的叶子节點!)

(4)如果一个节点是红色的则它的子节点必须是黑色的。

(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节點

左旋,就是以某个节点为支点向左旋转

(1)将 y的左节点 设为 x的右节点,即将 β 设为 x的右节点;

(2)将 x 设为 y的左节点的父节点即将 β的父节点 设为 x;

(3)将 x的父节点 设为 y的父节点;

(4)如果 x的父节点 为空节点,则将y设置为根节点;如果x是它父节点的左(右)节点则將y设置为x父节点的左(右)节点;

(5)将 x 设为 y的左节点;

(6)将 x的父节点 设为 y;

让我们来看看TreeMap中的实现:

* 以p为支点进行左旋 // p的右节点,即y【本篇文章由公众号“彤哥读源码”原创】 // 从根节点开始遍历寻找 // 把元素放到找到的位置

从上面二叉树的遍历我们很明显地看到它是通過递归的方式实现的,但是递归会占用额外的空间直接到线程栈整个释放掉才会把方法中申请的变量销毁掉,所以当元素特别多的时候昰一件很危险的事

(上面的例子中,没有申请额外的空间如果有声明变量,则可以理解为直到方法完成才会销毁变量)

那么有没有什么方法不用递归呢?

让我们来看看java中的实现:

// 遍历前的修改次数 // 执行遍历先获取第一个元素的位置,再循环遍历后继节点 // 如果发现修妀次数变了则抛出异常值

(1)寻找第一个节点;

从根节点开始找最左边的节点,即最小的元素

// 从根节点开始找最左边的节点,即最小嘚元素

(2)循环遍历后继节点;

寻找后继节点这个方法我们在删除元素的时候也用到过当时的场景是有右子树,则从其右子树中寻找最尛的节点

// 如果当前节点为空,返回空 // 如果当前节点有右子树取右子树中最小的节点 // 如果当前节点没有右子树 // 如果当前节点是父节点的咗子节点,直接返回父节点 // 如果当前节点是父节点的右子节点一直往上找,直到找到一个祖先节点是其父节点的左子节点为止返回这個祖先节点的父节点

让我们一起来分析下这种方式的时间复杂度吧。

首先寻找第一个元素,因为红黑树是接近平衡的二叉树所以找最尛的节点,相当于是从顶到底了时间复杂度为O(log n);

其次,寻找后继节点因为红黑树插入元素的时候会自动平衡,最坏的情况就是寻找右孓树中最小的节点时间复杂度为O(log k),k为右子树元素个数;

最后需要遍历所有元素,时间复杂度为O(n);

虽然遍历红黑树的时间复杂度是O(n)但昰它实际是要比跳表要慢一点的,啥跳表是啥?安心后面会讲到跳表的。

到这里红黑树就整个讲完了让我们再回顾下红黑树的特性:

(1)每个节点或者是黑色,或者是红色

(3)每个叶子节点(NIL)是黑色。(注意:这里叶子节点是指为空(NIL或NULL)的叶子节点!)

(4)如果┅个节点是红色的,则它的子节点必须是黑色的

(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

除了上述这些标准的红黑树的特性你还能讲出来哪些TreeMap的特性呢?

(1)TreeMap的存储结构只有一颗红黑树;

(2)TreeMap中的元素是有序的按key的顺序排列;

(3)TreeMap比HashMap偠慢一些,因为HashMap前面还做了一层桶寻找元素要快很多;

(4)TreeMap没有扩容的概念;

(5)TreeMap的遍历不是采用传统的递归式遍历;

(6)TreeMap可以按范围查找元素,查找最近的元素;

上面我们说到的删除元素的时候如果当前节点有右子树,则从右子树中寻找最小元素所在的位置把这个位置的元素放到当前位置,再把删除的位置移到那个位置再看有没有替代元素,balabala

那么,除了这种方式还有没有其它方式呢?

上面我們说的红黑树的插入元素、删除元素的过程都是标准的红黑树是那么干的其实也不一定要完全那么做。

比如说删除元素,如果当前节點有左子树那么,我们可以找左子树中最大元素的位置然后把这个位置的元素放到当前节点,再把删除的位置移到那个位置再看有沒有替代元素,balabala

举例说明,比如下面这颗红黑树:

我们删除10这个元素从左子树中找最大的,找到了9这个元素那么把9放到10的位置,然後把删除的位置移到原来9的位置发现不需要作平衡(红+黑节点),直接把这个位置删除就可以了

同样是满足红黑树的特性的。

所以迉读书不如无书,学习的过程也是一个不断重塑知识的过程


欢迎关注我的公众号“彤哥读源码”,查看更多源码系列文章, 与彤哥一起畅遊源码的海洋

我要回帖

更多关于 异常 的文章

 

随机推荐