常见数据结构-栈-队列-数组-链表-哈希表
数据结构
数据结构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率
持续更新,学一个记一个~
栈
栈模型:
一端开口 ==栈顶==| |
| |
| |
| |
| |
|____________________|一端封闭 ==栈底==
- 数据进入栈模型的过程称为:压/进栈
| | | |
| | [数据 A] | [数据 D] | <- 栈顶元素
| | [数据 B] | [数据 C] |
| | [数据 C] | [数据 B] |
| | [数据 D] | [数据 A] | <- 栈底元素
|____________________| |____________________|
- 数据离开栈模型的过程称为:弹/出栈
出栈顺序为从栈顶元素到栈底元素
栈是一种先进后出的模型
队列
队列模型:
一端开口 ==后端==| |
| |
| |
| |
| |
| |一端开头 ==前端==
- 数据从后端进入队列模型的过程称为:入队列
| |
| | [数据 A]
| | [数据 B]
| | [数据 C]
| | [数据 D]
| | ---------------------------------------------------------- 入队列方向\|/ 后端
| |
| [数据 D] |
| [数据 C] |
| [数据 B] |
| [数据 A] |
| |\|/ 前端出队列方向
- 数据从前端离开队列模型的过程称为:出队列
队列是一种先进先出的模型
数组
数组模型:
___0___1___2___3___4___5___6___
| [A] [B] [C] [D] [E] [F] [G] |
|_____________________________|
- 查询数据通过索引定位,查询任意数据耗时相同,查询数度快
- 删除数据时,要将原始数据删除,同时后面每个数据前移,删除效率低
- 添加数据时,添加位置后的每个数据后移,再添加元素,添加效率极低
数组是一种查询快,增删慢的模型
链表
链表的每一个元素被称为结点
结点模型:
[地址1]
________________
| [数据] [地址2] |
|_______________|-----------------------------------------
地址1:结点的==存储位置(地址)==
数据:存储具体的==数据==
地址2:下一个结点的==地址==
头结点模型:
______________
| [head] [^] |
|____________|
-----------------------------------------
^:结点指向==空地址(表示结束)==
链表模型链接过程示例
- 给头结点存储一个数据A,保存在地址11的位置:
[11]
_______________ ___________
| [head] [11] | --> | [A] [^] |
|_____________| |_________|
- 再存储一个数据C,保存在地址37位置
[11] [37]
_______________ ____________ ___________
| [head] [11] | --> | [A] [37] | --> | [C] [^] |
|_____________| |__________| |_________|
- 再存储一个数据D,保存在地址96位置
[11] [37] [96]
_______________ ____________ ____________ ____________
| [head] [11] | --> | [A] [37] | --> | [C] [96] | --> | [D] [^] |
|_____________| |__________| |__________| |__________|
链表模型添加数据过程示例
在数据AC之间添加一个数据B,保存在地址54地址
[11] [37] [96]
_______________ ____________ ____________ ____________
| [head] [11] | --> | [A] [37] | --> | [C] [96] | --> | [D] [^] |
|_____________| |__________| |__________| |__________|[54]___________| [B] [^] ||_________|
- 数据B对应的下一个数据地址指向数据C
[11] [37] [96]
_______________ ____________ ____________ ____________
| [head] [11] | --> | [A] [37] | --> | [C] [96] | --> | [D] [^] |
|_____________| |__________| |__________| |__________|↑[54]____________| [B] [37] ||__________|
- 数据A对应的下一个数据地址指向数据B
[11] [37] [96]
_______________ ____________ ____________ ____________
| [head] [11] | --> | [A] [54] | | [C] [96] | --> | [D] [^] |
|_____________| |__________| |__________| |__________|| ↑| [54]| ____________|--------> | [B] [37] ||__________|
链表模型删除数据过程示例
删除数据BD之间的数据C
[11] [37] [96]
_______________ ____________ ____________ ____________
| [head] [11] | --> | [A] [54] | | [C] [96] | --> | [D] [^] |
|_____________| |__________| |__________| |__________|| ↑| [54]| ____________|--------> | [B] [37] ||__________|
- 数据B对应的下一个数据地址指向数据D
[11] [37] [96]
_______________ ____________ ____________ ____________
| [head] [11] | --> | [A] [54] | | [C] [96] | --> | [D] [^] |
|_____________| |__________| |__________| |__________|| ↑| [54] || ____________ ||--------> | [B] [96] |-------||__________|
- 数据C删除
[11] [96]
_______________ ____________ ____________
| [head] [11] | --> | [A] [54] | | [D] [^] |
|_____________| |__________| |__________|| ↑| [54] || ____________ ||--------> | [B] [96] |-------||__________|
- 查询数据D是否存在,必须从头(head)开始查询
- 查询第n个数据,也必须从头(head)开始查询
链表是一种增删快,查询慢的模型(对比数组)
哈希表
JDK 8 之前,底层采用数据+链表实现,可以说是一个元素为链表的数组
JDK 8 以后,在长度比较长的时候,底层实现了优化
哈希表存储元素示例(如何保证元素唯一性)
待存储元素为:
“hello”
“world”
“java”
“world”
“通信”
“软件”
为了方便演示,计算各元素的哈希值为(实际计算机操作是每一次添加都进行独立计算):
“hello” ---- 99162322
“world” ---- 113318802
“java” ---- 3254818
“world” ---- 113318802
“通信” ---- 1179395
“软件” ---- 1179395
在JDK说明文档中看到HashSet的空参构造方法的描述为:
HashSet():构造一个空的集合;支持HashMap实例具有默认初始容量(16)和加载因子(0.75)。
对于这个加载因子为什么是0.75我在晚上查阅了很多资料,大部分说它是与泊松分布直接相关,直到后面我又看到一篇反驳的博客,链接都放在这里了,对学术研究还是要保持好奇,保持质疑的精神啊
支持与泊松分布直接相关
反驳
据此我们得到HashSet的模型:
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]
_________________________________________________________________________________
| | | | | | | | | | | | | | | | |
|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
那么如何存储各元素的哈希值到哈希表中呢?
将各元素的哈希值进行对16取余,余数是几就存储到几中
“hello” ---- 99162322 % 16 => 2
“world” ---- 113318802 % 16 => 2
“java” ---- 3254818 % 16 => 2
“world” ---- 113318802 % 16 => 2
“通信” ---- 1179395 % 16 => 3
“软件” ---- 1179395 % 16 => 3
显然我们只需要用到编号为2的位置和编号为3的位置,所以下面的演示省略未用到的部分(实际没用到也是存在的)
[2] [3] ___________________________
..... | | | .....|____________|____________|
- 尝试添加“hello”
根据“hello”的哈希值计算出它的存储位置是2,此时2号位没有元素,所以直接添加元素:
[2] [3]
___________________________
| “hello” | |
|_____________|____________|
- 尝试添加“world”
根据“world”的哈希值计算出它的存储位置也是2,此时2号位已经有元素,所以需要和已存在的元素进行比较,首先比较哈希值:
99162322 != 113318802
“hello” “world”
第一步对比发现二者哈希值不同,所以直接添加元素,元素也存储在2号位,但是是以链表的形式存储:
[2] [3]
___________________________
| “hello” | |
|______|______|____________|↑___________| “world” ||_________|
- 尝试添加“java” 同第二步,比较待添加元素和已存在所有元素的哈希值
99162322 != 3254818
“hello” “java”
---------------------------
113318802 != 3254818
“world” “java”
依次比较所有已存在元素后发现哈希值均不同,所以直接添加元素,同样以链表的形式存储在2号位:
[2] [3]
___________________________
| “hello” | |
|______|______|____________|↑___________| “world” ||_________|↑___________| “java” ||_________|
- 尝试添加“world”
同第二步,比较待添加元素和已存在所有元素的哈希值
99162322 != 113318802
“hello” “world”
---------------------------
113318802 == 113318802
“world” “world”
---------------------------
3254818 != 113318802
“java” “world”
依次比较所有已存在元素后发现哈希值存在相同值,所以继续比较相同哈希值的元素内容是否相同:
113318802 == 113318802“world” == “world”
比较后发现内容一致,故跳过添加操作。
- 尝试添加“通信”
根据“通信”的哈希值计算出它的存储位置是3,此时3号位没有元素,所以直接添加元素:
[2] [3]
____________________________
| “hello” | “通信” |
|______|______|____________|↑___________| “world” ||_________|↑___________| “java” ||_________|
- 尝试添加“软件”
根据“软件”的哈希值计算出它的存储位置也是3,此时3号位已经有元素,所以需要和已存在的元素进行比较,首先比较哈希值:
1179395 == 1179395“通信” “软件”
比较后发现二者哈希值相同,所以继续比较元素内容是否相同:
1179395 == 1179395“通信” != “软件”
发现内容并不相同,故以链表的形式添加元素:
[2] [3]
____________________________
| “hello” | “通信” |
|______|______|_____|______|↑ ↑___________ __________| “world” | | “软件” ||_________| |_______|↑___________| “java” ||_________|
至此,哈希表添加元素操作演示完毕
常见数据结构-栈-队列-数组-链表-哈希表相关推荐
- Java集合常见数据结构-栈/队列/数组/链表/红黑树
数组 链表 红黑树
- 常见的数据结构:栈 队列 数组 链表 红黑树——List集合 _ HashSet集合、可变参数 collections集合 Map集合
2021-06-07复习java 一.常见的数据结构 栈(先进后出) 队列 数组 链表 红黑树 二.List集合_介绍&常用方法 ArrayList集合 Linkedlist集合 三.Hash ...
- 【Java8】堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,/统计字符个数,debug,斗地主,Collections,TreeSet
文章目录 1.堆栈/队列/数组/链表:数据结构即计算机组织管理数据的方式,堆栈指的是内存图中的栈,不是堆 2.红黑树:二查,二查平,二查平1倍 3.List子接口:集合,IndexOutOfBound ...
- 栈,队列和链表三者之间的关系与区别
最近一直在学习算法,刷算法题,但是自从大学毕业以来,数据结构的知识都还给老师了,只会个数组,所以前期刷的题目也都是有关数组的 最近跟着小册重学了一遍数据结构,今天就记录一下栈,队列和链表三者之间的关系 ...
- 【从蛋壳到满天飞】JS 数据结构解析和算法实现-哈希表
前言 [从蛋壳到满天飞]JS 数据结构解析和算法实现,全部文章大概的内容如下: Arrays(数组).Stacks(栈).Queues(队列).LinkedList(链表).Recursion(递归思 ...
- 数据结构与算法五:哈希表-哈希函数设计原则-哈希冲突解决方案
一.哈希表的定义: 二.哈希表举例: 哈希函数就是映射关系 三.哈希表应用举例: Leetcode上第387题: 思路:通过s.charAt(i)-'a'将字符串中的字符映射成hash表,出现一次,在 ...
- 算法训练Day6 | LeetCode:242. 有效的字母异位词(数组作哈希表);349. 两个数组的交集(Set作哈希表);202.快乐数 (Set作哈希表);1. 两数之和(Map作哈希表)
目录 LeetCode242. 有效的字母异位词 方法:数组作哈希表 1. 思路 2. 代码实现 3. 复杂度分析 4. 思考 Leetcode349. 两个数组的交集 方法一:用Set作HashMa ...
- 【Leetcode 专题五】数组和哈希表
目录 一.前言 二.解题思路和代码整理 2.1.数组重建 Leetcode283. 移动零 Leetcode27. 移除元素 Leetcode26. 删除有序数组中的重复项 2.2.数组双指针 Lee ...
- 【翻译】Programming Ruby——数组,哈希表和控制结构
数组和哈希表 Ruby的数组和哈希表是索引集合.两都都是保存对象集合并能通过键来读取.数组的键是数字,但是哈希表则支持对象作为键.它们都是随着新元素的加入要增长.在访问元素方面,数组效率比较高,但哈希 ...
最新文章
- 2021年还适合参加软件测试培训吗
- Microbiome:肠道菌群失衡促进高血压
- org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'xx' is defined
- python正态检验_Python检验数据是否正态分布
- 最短路径生成树计数+最短路径生成树
- 2018/7/6-纪中某C组题【jzoj1192,jzoj1397,jzoj1736】
- python新建一个文件夹需要重新安装模块吗_解决pycharm每次新建项目都要重新安装一些第三方库的问题...
- java调用qq接口_用java代码怎么去请求腾讯接口并返回值
- 优化mysql数据库_MySQL数据库十大优化技巧
- [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换
- 关于C#的sqlite数据库操作类
- UESTC - 59 数据大搜索
- 元宇宙类电影这里全了!
- vs2019运行程序提示 程序无法正常启动(0xc000007b)解决方案
- 深刻认识 -- 立即数
- 基于Python的小游戏
- 工字型钢弹性截面模量计算公式_型钢计算公式2
- C#-iBatis.NET使用小结
- ffmpeg处理字幕
- Beautiful Soup属性和方法及文档
热门文章
- 中国航信2020java校招笔试题_航信校招java笔试题
- 输入圆柱的高和半径,求圆柱体积,volume=π×r 2 ×h 。要求定义和调用函数cylinder (r, h )计算圆柱体的体积。
- 7-2 长度质量计量单位换算(分数 5)
- 黄章出山的730天:牢牢掌控魅族,绝不放权!
- java传感器_传感器 - javawebsoa - 博客园
- Python环境的安装和配置
- UnixLinux 读书摘抄(简介)
- CardSlidePanel卡片左右划效果
- windows窗口置顶--Windows on Top
- 修改注册表,更改Win10版本,解决升级时无法“保留个人文件和应用”的问题