Java基础知识_Map集合、散列表、红黑树

一、Map介绍

1.1 为什么需要Map

前面我们学习的Collection叫做集合,它可以快速查找现有的元素

而Map在《Core Java》中称之为映射

映射的模型图是这样的:

 

 那为什么我们需要这种数据存储结构呢??举个例子

  作为学生来说,我们根据学号来区分不同的学生。只要我们知道学号,就可以获取对应的学生信息,这就是Map映射的作用。

  生活中还有很多这样的例子:只要你掏出身份证(Key),那就可以证明是你自己(value)

 

1.2 Map与Collection的区别

Map集合的特点:

  将键映射到值得对象,一个映射不能包含重复,每个键最多只能映射到一个值

Map和Collection集合得区别

  1、Map集合存储元素是成对出现得,Map键是唯一得,值是可以重复的。

  2、Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,list是可重复的

要点:

  1、Map集合的数据结构针对键有效,跟值无关

  2、Collection集合的数据结构针对元素有效

 

1.3 Map的功能

简单的常用Map功能概述

1:添加功能

  V put (K key , V value)添加元素

  如果键的第一次存储,就直接存储元素,返回null

  如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

2:删除功能

  void clear();移除所有的键值对元素

  V remove(Object key);根据键删除值,并把值返回

3、判断功能

  boolean containsKey(Object key);判断集合是否包含指定的键

  boolean containsValue(Object value);判断集合是否包含指定的值

  boolean isEmpty();判断集合是否为空

4、获取功能

  Set<Map.Entry<K key , V value>> entrySet();返回的是键值对对象的集合

  V get(Object key);根据键获取值

  Set<K> keySet();获取集合中所有的键的集合

  Collection<V> values;获取集合中所有值的集合

5、长度功能

  int size() 返回集合中键值对的对数

 

二、散列表介绍

无论是Set还是Map,我们会发现有对应的HashSet和HashMap

首先我们也得回顾一下数组和链表

链表和数组都可以按照人们的意愿来排序

链表和数组都可以按照人们的意愿来排列元素的次序,他们可以说是有序的(存储顺序和取出的顺序是一致的)

但同时,这会带来缺点:想要获取某个元素,就要访问所有的元素,直到找到为止

这会让我们消耗很多的时间在里面,遍历访问元素。

而还有另外的一些存储结构:不在意元素的顺序,能够快速的查找元素的数据

其中就有一种常见的:散列表

 

2.1 散列表工作原理

散列表为每个对象计算出一个整数,称为散列码。根据这些计算出来的整数(散列码)保存在相对应的位置上。

在Java中,散列表用的是链表数组实现的,每个列表称之为桶。一个桶上可能遇到被占用的情况(hashCode散列码相同,就存储在同一个位置上),这种情况是无法避免的,这种现象称之为:散列冲突。

  此时,需要用该对象与桶上的对象进行比较,看看该对象是否存在桶子上了,如果存在就不添加了,如果不存在则添加到桶子上

  当然了,如果hashcode函数设计得足够好,桶的数目也足够,这种比较少的

  在jdk1.8中,当同一个hash值的节点数不小于8时,将不再以单链表的形式存储了,会被调整成一颗红黑树。

 

如果散列表太满,时需要对散列表再散列,创建一个桶数更多的散列表,并将原有的元素插入到新表中,丢弃原来的表。

  装填因子决定了何时对散列表再散列

  装填因子默认是0.75,如何表中超过了75%的位置已经填入了元素,那么这个表就会用双倍的桶数自动进行再散列。

 

三、红黑树的介绍

各种常见的树的用途

AVL树:最早的平衡二叉树之一。应用相对其他数据结构比较少,windows对进程地址空间的管理用到了AVL树。

红黑树:平衡二叉树,广泛用在C++的STL中。如map和set都是用红黑树实现的。

B/B+树:用在磁盘文件组织,数据索引和数据库索引

Trie树(字典树):用于统计和排序大量字符串,如自动机

3.1 回顾二叉树

利用二叉树的特性,我们一般可以很快的查找到对应的元素,可是二叉树也有个例(最坏)的情况,线性

 

 上述符合二叉树的特性,但是它是线性的,完全没有树的用处

树是要均衡才能将它的优点展示出来的,比如下面这种

因此,就有了平衡树这个概念,红黑树就是一种平衡树,它可以保证二叉树基本上都符合矮矮胖胖的结构,也就是均衡

 

3.2  2-3树

讲到了平衡树就不得不说了最基础的2-3树,2-3树长得是这个样子

 

 在二叉查找树,我们插入节点的过程是这样的:小于节点的值往右继续与左子节点比,大于则继续与右子节点比,直到某节点左或右子节点为空,把值插入进去,这样无法避免偏向问题。

而2-3树不一样:它插入的时候可以保持树的平衡

在2-3树插入的时候,可以简单总结为两个操作

  合并2-节点为3-节点,扩充将3-节点扩充为一个4-节点

  分解4-节点为3-节点,节点3-节点为2-节点

  使得树平衡

合并分解的操作还是比较复杂的,以后详细说

 

3.3 从2-3树到红黑树

由于2-3树为了保持平衡性,在维护的时候是需要大量节点交换的!这些变化实际代码中是很复杂的,大佬们在2-3的理论上发明了红黑树

红黑树是对2-3查找树的改进,它能用一种统一的方式完成所有变换

红黑树是一种平衡二叉树,因此它没有3-节点。那么红黑树是怎么将3-节点来改进成全都是二叉树的呢?

红黑树就是字面上的意思,有红色的节点,有黑色的节点;

一颗典型的二叉树:

 

 将红色节点的左链接画平之后:得到2-3平衡树:

 

 3.4 红黑树的基础知识

前面已经说了,红黑树是在2-3的基础上实现的一种树,它能够用统一的方式完成所有变换。

红黑树用的是两种方式来代替2-3树不断的节点交换操作

  旋转:顺时针旋转和逆时针旋转

  反色:交换红黑的颜色

这个两个实现比2-3树交换的节点(合并分解要方便一点)

 

红黑树为了保持平衡还是有制定一些约束的,遵守这些约束的才能叫做红黑树

1、红黑树是二叉搜索树

2、根节点是黑色

3、每个叶子节点都是黑色的空节点(NIL节点)

4、每个红色节点的两个子节点都是黑色(从每个叶子到根的所有路径上不能有两个连续的红色节点

5、从任一节点到其每个叶子节点的所有路径都包含相同的数目的黑色节点(每一条树链上的黑色节点数量(称之为“黑高”)必须相等)。

 

3.5 红黑树总结

之后复习数据结构再好好总结细节,今天就稍微过一遍

posted @ 2019-09-08 21:52  chyblogs  阅读(273)  评论(0)    收藏  举报