16 张图带你搞懂 Java 数据结构,从此想不飘都难!(1)

读者福利

由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

更多笔记分享

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

2)链表

链表在物理存储空间是不连续的,但每个节点要么知道它的下一个节点是谁,要么知道它的上一个节点是谁,仿佛就像我们之间隔着千山万水,却心有灵犀一点链。像 LinkedList 就是最典型的链表结构,通过引用相互链接。

LinkedList 中的每一个元素都可以称之为节点(Node),每一个节点都包含三个项目:其一是元素本身,其二是指向下一个元素的引用地址,其三是指向上一个元素的引用地址。

LinkedList 看起来就像下面这个样子:

  • 第一个节点由于没有前一个节点,所以 prev 为 null;

  • 最后一个节点由于没有后一个节点,所以 next 为 null;

  • 这是一个双向链表,每一个节点都由三部分组成,前后节点和值。

相比 ArrayList,LinkedList 有以下优势:

1、LinkedList 允许内存进行动态分配,这就意味着内存分配是由编译器在运行时完成的,我们无需在 LinkedList 声明的时候指定大小。

2、LinkedList 不需要在连续的位置上存储元素,因为节点可以通过引用指定下一个节点或者前一个节点。也就是说,LinkedList 在插入和删除元素的时候代价很低,因为不需要移动其他元素,只需要更新前一个节点和后一个节点的引用地址即可。

3)栈

栈是一种非常有用的数据结构,它就像一摞盘子,第一个放在最下面,第二个放在第一个上面,第三个放在第二个上面,最后一个放在最上面。栈遵循后进先出的原则,也就是“Last In First Out”(简称 LIFO)——最后的一个进的,最先出去。

对于栈这样一个数据结构来说,它有两个常见的动作:

  • push,中文释义有很多种,我个人更喜欢叫它“压入”,非常形象。当我们要把一个数据放入栈的顶部,这个动作就叫做 push

  • pop,同样的,我个人更喜欢叫它“弹出”,带有很强烈的动画效果,有没有?当我们要从栈中移除一个数据时,这个动作就叫做 pop

4)队列

队列,只允许在队尾添加数据,队首移除数据。队列在 Java 中的出现频率非常高,有各种不同的类来满足不同的场景需求。像优先级队列 PriorityQueue、延时队列 DelayQueue 等等。队列遵循的是 First In First Out,缩写为 FIFO,也就是先进先出,第一个进入队列的第一个先出来。

再来说非线性数据结构。

1) 树

树是一种典型的非线性结构,它是由 n(n>0)个有限节点组成的一个具有层次关系的集合。之所以叫“树”,是因为这种数据结构看起来就像是一个倒挂的树,只不过根在上,叶在下。树形数据结构有以下这些特点:

  • 每个节点都只有有限个子节点或无子节点;

  • 没有父节点的节点称为根节点;

  • 每一个非根节点有且只有一个父节点;

  • 除了根节点外,每个子节点可以分为多个不相交的子树。

下图展示了树的一些术语:

根节点是第 0 层,它的子节点是第 1 层,子节点的子节点为第 2 层,以此类推。

  • 深度:对于任意节点 n,n 的深度为从根到 n 的唯一路径长,根的深度为 0。

  • 高度:对于任意节点 n,n 的高度为从 n 到一片树叶的最长路径长,所有树叶的高度为 0。

树又可以细分为下面几种:

1、普通树:对子节点没有任何约束。

2、二叉树:每个节点最多含有两个子节点的树。 二叉树按照不同的表现形式又可以分为多种。

2.1、普通二叉树:每个子节点的父节点不一定有两个子节点的二叉树。

2.2、完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第 d 层外,其它各层的节点数目均已达最大值,且第 d 层所有节点从左向右连续地紧密排列。

2.3、满二叉树:一颗每一层的节点数都达到了最大值的二叉树。有两种表现形式,第一种,像下图这样(每一层都是满的),满足每一层的节点数都达到了最大值 2。

3、二叉查找树:英文名叫 Binary Search Tree,即 BST,需要满足以下条件:

  • 任意节点的左子树不空,左子树上所有节点的值均小于它的根节点的值;

  • 任意节点的右子树不空,右子树上所有节点的值均大于它的根节点的值;

  • 任意节点的左、右子树也分别为二叉查找树。

3.1、平衡二叉树:当且仅当任何节点的两棵子树的高度差不大于 1 的二叉树。由前苏联的数学家 Adelse-Velskil 和 Landis 在 1962 年提出的高度平衡的二叉树,根据科学家的英文名也称为 AVL 树。

平衡二叉树本质上也是一颗二叉查找树,不过为了限制左右子树的高度差,避免出现倾斜树等偏向于线性结构演化的情况,所以对二叉搜索树中每个节点的左右子树作了限制,左右子树的高度差称之为平衡因子,树中每个节点的平衡因子绝对值不大于 1。

平衡二叉树的难点在于,当删除或者增加节点的情况下,如何通过左旋或者右旋的方式来保持左右平衡。

红黑树是一种常见的平衡二叉树,节点是红色或者黑色,通过颜色的约束来维持着二叉树的平衡:

  • 每个节点都只能是红色或者黑色

  • 根节点是黑色

  • 每个叶节点(NIL 节点,空节点)是黑色的。

  • 如果一个节点是红色的,则它两个子节点都是黑色的。也就是说在一条路径上不能出现相邻的两个红色节点。

  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

4、B 树:一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多于两个的子树。

5、B+ 树:B 树的变体。

HashMap 里面的 TreeNode 就用到了红黑树,而 B 树、B+ 树在数据库的索引原理里面有典型的应用。

2)哈希表

哈希表(Hash Table),也叫散列表,是一种可以通过关键码值(key-value)直接访问的数据结构,它最大的特点就是可以快速实现查找、插入和删除。其中用到的算法叫做哈希,就是把任意长度的输入,变换成固定长度的输出,该输出就是哈希值。像 MD5、SHA1 都用的是哈希算法。

每一个 Java 对象都会有一个哈希值,默认情况就是通过调用本地方法执行哈希算法,计算出对象的内存地址 + 对象的值的关键码值。

数组的最大特点就是查找容易,插入和删除困难;而链表正好相反,查找困难,而插入和删除容易。哈希表很完美地结合了两者的优点, Java 的 HashMap 在此基础上还加入了树的优点。

哈希表具有较快(常量级)的查询速度,以及相对较快的增删速度,所以很适合在海量数据的环境中使用。

对于任意两个不同的数据块,其哈希值相同的可能性极小,也就是说,对于一个给定的数据块,找到和它哈希值相同的数据块极为困难。再者,对于一个数据块,哪怕只改动它的一个比特位,其哈希值的改动也会非常的大——这正是 Hash 存在的价值!

尽管可能性极小,但仍然会发生,如果哈希冲突了,Java 的 HashMap 会在数组的同一个位置上增加链表,如果链表的长度大于 8,将会转化成红黑树进行处理——这就是所谓的拉链法(数组+链表)。

3)图

图是一种复杂的非线性结构,由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G 表示一个图,V 是图 G 中顶点的集合,E 是图 G 中边的集合。

Ending

Tip:由于文章篇幅有限制,下面还有20个关于MySQL的问题,我都复盘整理成一份pdf文档了,后面的内容我就把剩下的问题的目录展示给大家看一下

如果觉得有帮助不妨【转发+点赞+关注】支持我,后续会为大家带来更多的技术类文章以及学习类文章!(阿里对MySQL底层实现以及索引实现问的很多)

吃透后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值