当前位置: 首页 > wzjs >正文

html5移动网站开发重庆seo霸屏

html5移动网站开发,重庆seo霸屏,怎么用flash做游戏下载网站,浦东建设网站制作今天尝试刨一下TreeMap的祖坟。 底层结构对比 先来看一下与HashMap、LinkedHashMap和TreeMap的对比,同时就当是复习一下: HashMap使用数组存储数据,并使用单向链表结构存储hash冲突数据,同一个冲突桶中数据量大的时候&#xff…

今天尝试刨一下TreeMap的祖坟。

底层结构对比

先来看一下与HashMap、LinkedHashMap和TreeMap的对比,同时就当是复习一下:

  1. HashMap使用数组存储数据,并使用单向链表结构存储hash冲突数据,同一个冲突桶中数据量大的时候(默认超过8)则使用红黑树存储冲突数据。
  2. LinkedHashMap使用数组+双向链表存储数据,冲突数据存储方式同HashMap。
  3. TreeMap使用红黑树存储数据,注意是直接使用红黑树,不使用table数组。

关于排序特性

  1. HashMap无顺序,不能保持顺序。
  2. LinkedHashMap能保持写入的顺序,遍历的时候可以按照写入顺序获取数据。
  3. TreeMap是有序的Map,自动按照key值排序存储,遍历时获取到的是有序数据。

需要注意LinkedHashMap和TreeMap在顺序方面的区别,LinkedHashMap只能保持写入顺序,从“排序”的角度讲,他实际是无序的。

只有TreeMap是可以实现自动排序的。

TreeMap按照什么排序?

TreeMap底层支持两种排序方式:

  1. TreeMap对象实例化时传入comparator对象。
  2. key值对象实现Comparable接口。

如果以上两点都不能满足的话,向TreeMap对象put数据的时候会抛出运行时异常。

比如TreeMap<String,Object>,由于String实现了Comparable接口,所以是没有问题的。

但是如果自定义的对象,没有实现Comparable接口,同时在TreeMap实例化的时候没有设置comparator对象,则该TreeMap对象实际是不可用的。

TreeMap是否可以存储null?

指的是,是否可以存储key为空的数据?我们知道HashMap是可以支持唯一一个null对象的。

很多人都说不可以,但是我觉得有条件可以,但是没做测试(因为感觉则个问题其实有点扯)。

条件是实例化TreeMap对象的时候指定comparator对象,同时,该comparator对象的compare方法可以支持null。

研究TreeMap的put源码,也可以发现对以上说法的支持:

Comparator<? super K> cpr = comparator;if (cpr != null) {do {parent = t;cmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}else {if (key == null)throw new NullPointerException();...省略若干代码

可以发现如果有comparator的话,put方法不会立即抛出异常。但是如果comparator对象的compare方法不能支持null的话,一样会抛出异常。

put方法

由于TreeMap支持自动排序,所以put方法会检查是否满足规则。

不满足排序规则,抛出异常。

否则,按照红黑树算法规则要求,创建红黑树,存储数据。

所以这里就涉及到一个重要的数据结构:红黑树。

二叉树BST & 平衡二叉树AVL

红黑树是树结构的一种,是比二叉树和平衡二叉树更加复杂的一种数据结构。所以我们先从简单的入手,了解一下二叉树。

树结构其实是实现了子排序的一种数据结构,我们说到的树结构一般指的是二叉树、也叫二叉搜索树(BST - Binary Search Tree),定义:它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

二叉搜索树的插入、搜索操作所花的时间都和树的高度成正比。因此,如果共有n个元素,那么平均每次操作需要O(logn)的时间。

二叉搜索树的特性并不能保证他是平衡的,也就是说,极端情况下,一颗二叉搜索树从根节点开始,只有左节点、没有右节点(比如一直按照从大到小或者相反顺序插入二叉树),这种情况下,二叉树就蜕变成了链表,查询时间复杂度就会下降为O(n)。

改善二叉树这一缺点的经典数据结构是平衡二叉树AVL(Adelson-Velsky and Landis Tree,以两位发明者命名)。平衡二叉树的特性:

1.本身首先是一棵二叉搜索树。
2.带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。

一颗平衡二叉树在新节点插入之后可能会失衡,包括以下四种场景:

左左失衡LL

插入的数据在左侧不平衡树的左侧,这种情况下需要进行右旋操作再次平衡:
在这里插入图片描述
我们需要记住一个概念:平衡二叉树失衡之后通过旋转动作使得它再次平衡的处理,只是针对失衡的子树、不需要对整个树进行操作。比如上图新的节点1加入之后,导致pivot节点7一侧的树失衡,我们需要处理的是包含pivot节点的root节点的左侧树这一部分子树,右侧节点18下即使有再多的节点,也不需要处理。

右旋操作的实质是:以pivot节点7为支点做顺时针旋转,旋转之后7变为自己原来父节点的父节点、7的左节点不变,7的右节点变为7原来的父节点的左节点。

右右失衡RR

插入的节点在右侧不平衡树的右侧,这种情况下需要左旋:
在这里插入图片描述
左旋操作的实质是:以pivot节点18为支点做逆时针旋转,旋转之后18变为自己原来父节点的父节点、18的右节点不变,18的左节点变为18原来的父节点的右节点。

左右失衡LR

插入的新节点在左侧不平衡树的右侧。先左旋再右旋
在这里插入图片描述

右左失衡LR

插入的节点在右侧不平衡树的左侧,先右旋再左旋:
在这里插入图片描述
平衡二叉树具有:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1 这一特性,这一严格条件会导致每次插入新节点之后总会大概率破坏平衡、从而必须要通过上述的旋转操作使其再次达到平衡,旋转操作会影响数据插入的效率。

红黑树可以解决这一问题。

红黑树

红黑树是一种带颜色(节点是红色或者黑色)的平衡二叉树,具有以下特性:
性质1. 结点是红色或黑色。
性质2. 根结点是黑色。
性质3. 所有叶子都是黑色。(叶子是NIL结点)
性质4. 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
性质5. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。

红黑树新加入节点的颜色默认为黑色,因为根据红黑树性质4,每个红色节点的两个子节点都是黑色。所以,新加入节点如果是黑色的话,可以检查其父节点如果是红色的话,可以自动满足性质4从而减少再平衡操作、提高数据加入的效率。这一点可以通过TreeMap的put方法源码得到验证:

public V put(K key, V value) {Entry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}int cmp;Entry<K,V> parent;// split comparator and comparable pathsComparator<? super K> cpr = comparator;if (cpr != null) {do {parent = t;cmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}else {if (key == null)throw new NullPointerException();@SuppressWarnings("unchecked")Comparable<? super K> k = (Comparable<? super K>) key;do {parent = t;cmp = k.compareTo(t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}Entry<K,V> e = new Entry<>(key, value, parent);if (cmp < 0)parent.left = e;elseparent.right = e;fixAfterInsertion(e);size++;modCount++;return null;}

put方法前半部分逻辑比较简单,为新节点找到合适的位置加入,之后会调用fixAfterInsertion检查是否破坏了红黑树的规则从而需要执行再平衡操作:

private void fixAfterInsertion(Entry<K,V> x) {x.color = RED;while (x != null && x != root && x.parent.color == RED) {if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {Entry<K,V> y = rightOf(parentOf(parentOf(x)));if (colorOf(y) == RED) {setColor(parentOf(x), BLACK);setColor(y, BLACK);setColor(parentOf(parentOf(x)), RED);x = parentOf(parentOf(x));} else {if (x == rightOf(parentOf(x))) {x = parentOf(x);rotateLeft(x);}setColor(parentOf(x), BLACK);setColor(parentOf(parentOf(x)), RED);rotateRight(parentOf(parentOf(x)));}} else {Entry<K,V> y = leftOf(parentOf(parentOf(x)));if (colorOf(y) == RED) {setColor(parentOf(x), BLACK);setColor(y, BLACK);setColor(parentOf(parentOf(x)), RED);x = parentOf(parentOf(x));} else {if (x == leftOf(parentOf(x))) {x = parentOf(x);rotateRight(x);}setColor(parentOf(x), BLACK);setColor(parentOf(parentOf(x)), RED);rotateLeft(parentOf(parentOf(x)));}}}root.color = BLACK;}

fixAfterInsertion方法首先判断其父节点是红色的话,则不做任何操作。

get方法

根据红黑树查找算法查找并返回数据,红黑树是平衡二叉树,查询时间复杂度为O(log(n))。

key遍历

比如调用TreeMap.keySet方法,采用遍历二叉树算法,按照从小到大的顺序返回所有key值组成的循环器。

我该使用哪一个?

需要用到Map的时候,到底该使用哪一个的问题:

  1. 我只需要一个存储数据的容器,没有具体要求的话,用HashMap。
  2. 存储数据后,有按照存储顺序获取数据的需求,采用LinkedHashMap。
  3. 希望存储数据的同时,帮助实现自动排序,采用TreeMap。

性能的问题,其实几乎不需要考虑,不过我们还是需要知道:

  1. HashMap和LinkedHashMap查询速度快,理想情况下时间复杂度几乎是O(1)。
  2. HashMap写入速度最快,LinkedHashMap写入速度与HashMap几乎相同,TreeMap写入速度最慢(理论上,实际数据量小的情况下未必慢)。
  3. 遍历速度相差无几,理论上HashMap会慢一点,因为需要遍历空桶。

并发问题尚待研究,但是我们清楚地知道,以上三种均不具备线程安全性。

好梦!

http://www.dtcms.com/wzjs/129873.html

相关文章:

  • 卖产品怎么做网站武汉疫情最新动态
  • 网站内容与功能模块设计越秀seo搜索引擎优化
  • 网站ip如何做跳转开网店怎么推广运营
  • zion小程序开发网站移动端优化工具
  • 公众号开发服务招标公告长春seo主管
  • 国内适合个人做外贸的网站有哪些教育培训机构排名前十
  • 新网站建设方案申请网站域名要多少钱
  • 中徽园林建设有限公司网站深圳媒体网络推广有哪些
  • 织梦做的网站打开慢百度竞价排名推广
  • 杭州开发网站数据分析平台
  • 宁波网站推广软件哪家强些宁波seo网络推广报价
  • 2015做外贸网站好做吗杭州seo公司服务
  • 主流网站网络营销方式有哪些分类
  • 天津西青区旅游景点大全重庆网站seo教程
  • 如何做网站的内链优化武汉大学人民医院怎么样
  • 电商网站商品表设计哪里可以学seo课程
  • 上海做公司网站多少钱seo刷关键词排名工具
  • 网站开发 作品理念太原网络推广价格
  • 微官网与手机网站首页外贸网站优化公司
  • 长春做网站的公司有哪些百度官网认证免费
  • 爱山东app下载注册流程seo营销排名
  • 企业网站模板科技感百度购物平台客服电话
  • 网站建设吧如何免费制作自己的网站
  • 沧州做网站多少钱深圳全网信息流推广公司
  • web网站开发视频线上推广活动有哪些
  • wordpress取消邮件seo工程师是什么职业
  • 一份优秀的网络推广方案百度seo排名优
  • 网站空间后台怎么进入个人如何推广app
  • 顺德微网站建设整合营销传播的方法包括
  • 青岛市医疗保险网站免费的网页设计成品下载