本书:<<漫画算法小灰的算法之旅>>
作者:魏梦舒(@程序员小灰)
我是将本书中内容,重新整理一遍。基本是书中的内容,方便以后阅读查看!!!希望喜欢本书的小伙伴们可以相互学习,多多支持!

第二章数据结构基础

  • 什么是数组?
  • 什么是链表?
  • 什么是栈?
  • 什么是队列?
  • 什么是散列表?

1、数组是由有限个相同类型的变量所组成的有序集合,它的物理存储方式是顺序存储,访问方式是随机访问。利用下标查找数组元素的时间复杂度是O(1),中间插入、删除数组元素的时间复杂度是O(n)。
2、链表是一种链式数据结构,由若干节点组成,每个节点包含指向下一节点的指针。链表的物理存储方式是随机存储,访问方式是顺序访问。查找链表节点的时间复杂度是O(n),中间插入、删除节点的时间复杂度是O(1)。
3、栈是一种线性逻辑结构,可以用数组实现,也可以用链表实现。栈包括入栈和出栈操作,遵循先入后出的原则(FILO)。
4、队列也是一种线性逻辑结构,可以用数组实现,也可以用链表实现。队列包含入队和出队操作,遵循先入先出的原则(FIFO)。
5、散列表也叫哈希表,是存储Key-Value映射的集合。对于某一个Key,散列表可以在接近O(1)的时间内进行读写操作。散列表通过哈希函数实现Key和数组下标的转换,通过开放寻址法和链表法来解决哈希冲突。
2.1.1初始数组

  • 数组的特点是在内存中顺序存储,因此可以很好地实现逻辑上的顺序表。
  • 内存是由一个个连续的内存单元组成的,每一个内存单元都有自己的地址。在这些内存单元中,有些被其他数据占用了,有些是空闲的。
  • 数组中的每一个元素,都存储在小小的内存单元中,并且元素之间紧密排列,既不能打乱元素的存储顺序,也不能跳过某个存储单元进行存储。
  • 下标从0开始,一直到数组长度-1。

2.1.2数组的基本操作
1、读取元素:根据下标读取元素的方式——随机读取。
2、更新元素:直接利用数组下标,就可以把新值赋给该元素。
3、插入元素:数组的实际元素数量有可能小于数组的长度。
(1)尾部插入:直接把插入的元素放在数组尾部的空闲位置即可,等同于更新元素的操作。
(2)中间插入:先把插入位置及后面的元素向后移动,腾出地方,再把插入的元素放到对应的数组位置上。
(3)超范围插入:数组扩容。
创建一个新数组,长度是旧数组的2倍。再把旧数组中的元素统统复制过去。
4、删除元素:和插入操作的过程相反,如果删除的元素位于数组中间,其后的元素都需要向前挪动1位。
取巧方式:可以把最后一个元素复制到所删除元素的位置上,然后再删除掉最后一个元素。这样一来,无须进行大量的元素移动,时间复杂度降低为O(1)。这种方式只供作为参考,并不是删除元素时主流的操作方式。
总结:数组适合读操作多,写操作少的场景。
2.2什么是链表
链表(linked list)是一种在物理上非连续、非顺序的数据结构。由若干节点所组成。
链表在内存中的存储方式是随机存储。采用了见缝插针的方式,链表的 每一个节点分布在内存的不同位置,依靠next指针关联起来。
(1)单向链表的每一个节点又包含两部分。一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
(2)双向链表,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的pre指针。
2.2.2链表的基本操作
1、查找节点:
(1)将查找的指针定位到头节点。
(2)根据头节点的next指针,定位到第2个节点。
(3)依次类推,找到所要查询的节点。
2、更新节点:直接把旧数据替换成新数据即可。
3、插入节点
(1)尾部插入:把最后一个节点的next指针指向新插入的节点即可。
(2)头部插入:
第一步,把新节点的next指针指向原先的头节点。
第二步,把新节点变为链表的头节点。
(3)中间插入
第一步,把插入位置的前置节点的next指针指向插入的新节点。
第二步,将新节点的next指针指向前置节点的next指针原先所指向的节点。
只要内存空间允许,能够插入链表的元素是无穷无尽的,不需要像数组那样考虑扩容的问题。
4、删除元素
(1)尾部删除:把倒数第2个节点的next指针指向空即可
(2)头部删除:把链表的头节点设为原先头节点的next指针即可。
(3)中间删除:把要删除节点的前置节点的next指针,指向要删除元素的下一个节点即可。
总结:插入和删除的时间复杂度都是O(1)。
2.3栈和队列
2.3.1物理结构和逻辑结构

2.3.2什么是栈?
栈(stack)是一种线性数据结构,栈中的元素只能先入后出(Fast in Last Out,简称FILO)。
最早进入的元素存放的位置叫作栈底,最后进入的元素存放的位置叫作栈顶。
2.3.3栈的基本操作
1、入栈(push)
2、出栈(pop)
3、时间复杂度都是O(1)。
2.3.4什么是队列?
队列(queue)是一种线性数据结构,队列中的元素只能先入先出(First in First Out,简称FIFO)。队列的出口端叫作队头(front),队列的入口端叫作队尾(rear)。
总结:栈和队列既可以用数组来实现,也可以用链表来实现。
2.3.5队列的基本操作
1、入队(enqueue)
2、出队(dequeue)
3、循环队列
假设一个队列经过反复的入队和出队的操作,还剩下2个元素,在“物理”上分布于数组的末尾位置。这时又有一个新元素将要入队。在数组不做扩容的前提下,如何让新元素入队并确定新的队尾位置呢?可以开勇已出队元素留下的空间,让队尾指针重新指回数组的首位。这样一来,整个队列的元素就“循环”起来了。在物理存储上,队尾的位置也可以在队头之前。当再有元素入队时,将其放入数组首位,队尾指针继续后移即可。一直到(队尾下标+1)%数组长度=队头下标时,代表此队列真的已经满了。需要注意的是,队尾指针指向的位置永远空出1位,所以队列最大容量比数组长度小1。
总结:时间复杂度为O(1)。
2.3.6栈和队列的应用
1、栈的应用:
(1)实现递归的逻辑,栈可以回溯方法的调用链。
(2)面包屑导航,使用户在浏览页面时可以轻松的回溯到上一级或更上一级页面。
2、队列的应用:
(1)通常用于对“历史”的回放,也就是按照“历史”顺序,把“历史”重演一遍。
(2)在多线程中,争夺公平锁的等待队列,就是按照访问顺序来决定线程在队列中的次序的。
(3)网络爬虫实现网站抓取时,也是把待抓取的网站URL存入对列中,再按照存入对列的顺序来依次抓取和解析的。
3、双端队列:从队头一端可以入队或出队,从队尾一端也可以入队或出队。
4、优先队列:谁的优先级最高,谁先出队。
2.4神奇的散列表
哈希函数:把Key和数组下标进行转换的中转站。
index=HashCode(Key)%Array.length
2.4.3散列表的读写操作
1、写操作(put):在散列表中插入新的键值对。
哈希冲突:通过哈希函数把Key转化成数组下标,但是,由于数组的长度是有限的,当插入的Entry越来越多时,不同的Key通过哈希函数获得的下标有可能是相同的。
解决方法:(1)开放寻址法:寻找下一个空档位置。
(2)链表法:HashMap数组的每一个元素不仅是一个Entry对象,还是一个链表的头节点。每一个Entry对象通过next指针指向它的下一个Entry节点。当新来的Entry映射到与之冲突的数组位置时,只需要插入到对应的链表中即可。
2、读操作(get):通过给定的Key,在散列表中查到对应的Value。
3、扩容(resize):
(1)什么时候进行扩容?当经过多次元素插入,散列表达到一定饱和度时,Key映射位置发生冲突的概率会逐渐提高。这样一来,大量元素拥挤在相同的数组下标位置,形成很长的链表,对后续插入操作和查询操作的性能都有很大的影响。
(2)影响扩容的因素:

  • Capacity,即HashMap的当前长度。
  • LoadFactor,即HashMap的负载因子,默认值为0.75f。需要进行扩容的条件如下:HashMap.Size>=Capacity*LoadFactor。

(3)步骤

  • 扩容,创建一个新的Entry空数组,长度时原数组的2倍。
  • 重新Hash,遍历原Entry数组,把所有的Entry重新Hash到新数组中。因为长度扩大以后,Hash的规则也随之改变。
  • 经过扩容,原本拥挤的散列表重新变得稀疏,原有的Entry也重新得到了尽可能均匀的分配。
  • JDK直接阅读HashMap类的源码。
  • JDK 8和以前的版本有很大的不同。当多个Entry被Hash到同一个数组下标位置时,为了提升插入和查找的效率,HashMap会把Entry的链表转化为红黑树这种数据结构。

漫画算法:小灰的算法之旅相关推荐

  1. 漫画算法-小灰的算法之旅-排序算法(四)

    本文内容基于<漫画算法 小灰的算法之旅>,魏梦舒著. 1. 分类 1.1 时间复杂度为O(n^2)的排序算法 1.2 时间复杂度为O(nlogn)的排序算法 1.3 时间复杂度为线性的排序 ...

  2. 漫画算法小灰学习算法笔记

    写在前面的话: 学习算法,需要做的是领悟算法思想.理解算法对内存空间和性能的 影响,以及开动脑筋去寻求解决问题的最佳方案. 正文如下: 第1章 算法概述 1.1.2 什么是算法 算出1+2+3+4+5 ...

  3. 《漫画算法-小灰的算法之旅》第1章-算法概述读书笔记

    目录 1. 前言 2. 正文 2.1 算法和数据结构 2.1.1 什么是算法? 2.1.2 衡量算法好坏最重要的标准有哪两个? 2.1.3 什么是数据结构? 2.1.4 算法和数据结构有什么关系呢? ...

  4. 漫画算法:小灰的算法之旅_记忆之旅:流行网站的早期设计

    多年来,网站会逐渐更新和更改其设计风格,有时会变得更好,有时会变得更糟,但是无论您是否喜欢,Internet都是一个快速发展的有机体. 界面设计趋势一直在变化,您可以在过去的网站布局中看到这些想法. ...

  5. 漫画算法python篇_漫画算法:小灰的算法之旅(Python篇)(全彩)

    商品参数 漫画算法-小灰的算法之旅(Python篇) 定价 79.00 出版社 电子工业出版社 版次 出版时间 2020年03月 开本 16开 作者 魏梦舒 装帧 平装-胶订 页数 字数 ISBN编码 ...

  6. 开奖及送书|《漫画算法:小灰的算法之旅(Python篇)》

    2020 06 08 今天距2021年206天 这是一页河山第132次推文 点击上方蓝字"ITester软件测试小栈"关注我,每周一.三.五早上 07:30准时推送. 微信公众号后 ...

  7. 硬核图书系列:《漫画算法:小灰的算法之旅》

    小编说: 疫情像施了魔法一样,改变了我们每个人春节的轨迹.时间则从永远不够用突然变成了多得似乎不知干什么用.博文菌希望疫情没有改变我们那颗求知若渴的心. 人与人的差距也可能就在这个不知何时结束的假期中 ...

  8. 《漫画算法:小灰的算法之旅》读后

    第一章:算法概述 略 第二章:数据结构基础 基础定义 同量级函数: 存在函数f(n),使得f(n)/T(n)的极限值为不是0的常数.记作T(n) = O(f(n)),这里的O渐进时间复杂度,简称时间复 ...

  9. 好教程推荐系列:力扣LeetCode官网/labuladong的算法小抄/漫画算法小灰/刷题模板

    LeetCode官网 https://leetcode.com/ https://leetcode-cn.com/ labuladong的算法小抄 刷算法全靠套路,认准 labuladong 就够了! ...

最新文章

  1. R语言威布尔分布函数F Distribution(dweibull, pweibull, qweibull rweibull )实战
  2. Annovar注释的突变文件转MAF对象
  3. python类装饰器详解-Python类中的装饰器在当前类中的声明与调用详解
  4. iOS - 解决设置导航栏按钮图片变色的问题
  5. eas 在linux下安装_Linux下SVN的安装以及配置
  6. IBASE and ES change pointer
  7. 稳定匹配问题——稳定婚姻算法设计
  8. 历城职专学前计算机专业,历城职专学前教育专业2020学年第一学期技能运动会拉开帷幕...
  9. ForkJoin框架简单使用
  10. 【算法】剑指 Offer 56 - II. 数组中数字出现的次数 II 【重刷】
  11. java 冒泡算法_关于java中的冒泡算法
  12. Oauth三种认证方式
  13. 如何让计算机断开网络连接网络设置,电脑怎样设置定时断网,教您怎么设置
  14. unity3d 不规则外发光描边_PS发光字体教程
  15. Cisco Aironet系列AP的瘦胖转换
  16. android应用程序开发需要掌握的基础知识
  17. [OpenHarmony RK3568] (三)蓝牙芯片适配
  18. 程序员除了代码,连数字都神神秘秘的
  19. Lua程序设计随笔(5)
  20. 最新国家级贫困县名单

热门文章

  1. 哗啦啦王济民:餐饮新零售的发展方向
  2. 人工智能就业发展前景分析
  3. 百度网盘网页视频加速播放
  4. 多频超声波清洗换能器用于高精密清洗系统
  5. 重庆市江津区行政边界地图JSON文件精确到城镇街道-geojson-20211208
  6. 第一周工作总结及计划表
  7. 《Linux内核分析与实现》 第五周 读书笔记
  8. 树莓派安装python3.6_树莓派 Miniconda 无法安装最新 Python3.6
  9. [Expression Blend 4] [SketchFlow系列] Chapter 3 瞭解SketchFlow Map (下)
  10. mne画脑地形图出现Digmontage错误No digitization points found