Java数据结构也就是数据结构的实现方式,下面我分别详解Java数据结构的实现方式@mikechen
Java数组
1.数组的定义
数组是相同类型数据的有序集合,它用一组连续的内存空间,存储一组具有相同类型的数据。
2.数组的数据结构
如下图所示:
每个数组元素可以通过一个下标来访问它们。
数组按照索引查询元素,速度很快,时间复杂度为O(1)。
添加删除元素的操作很耗时间,时间复杂度为O(n)。
3.数组示例
public static void main(String[] args) { //定义一个静态初始化的数组,存出一批数据 int[] array = {13,24,42,1,4,99,45}; }
链表
1.链表定义
链表是一种常见的数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针。
2.链表数据结构
链表结是由许多节点构成的,每个节点都包含两部分:
1)数据部分:保存该节点的实际数据;
2)地址部分:保存的是上一个或下一个节点的地址。
3.链表的分类
链表分类主要包含如下三类:
1)单向链表
单链表的遍历方向单一,只能从链头一直遍历到链尾,所以有一个比较大的缺点:当要查询某一个节点的前一个节点时,只能再次从头进行遍历查询,因此效率比较低。
2)双向链表
双向链表指的是构成链表的每个结点中设立两个指针域:一个指向其直接前驱的指针域prev,一个指向其直接后继的指针域next。
这样形成的链表中有两个方向不同的链,故称为双向链表,如下图所示:
3)双向循环链表
双向循环链表将双向链表的头结点和尾结点链接起来也能构成循环链表,其称为双向循环链表。
如下图所示:
循环链表可以从任意一个结点开始遍历整个链表。
栈
1.栈的定义
栈:栈是一种计算机系统中的数据结构,它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶。
2.栈的示意图
如下图所示:
栈就像子弹壳装弹,一粒一粒压进去,但是打出来的时候是从上面打出来的,最先压进去的最后弹出来。
3.栈的操作
栈的操作常用的有:进栈(PUSH),出栈(POP)。
1)进栈(PUSH):将目标内存推入栈顶。
2)出栈(POP):从栈顶中移除目标。
队列
队列(Queue)是一种只允许在一端进行插入,在另一端进行删除的线性表结构。
1.队列的特点
- 允许插入的一端叫队尾;
- 允许删除的一端叫队头;
- 栈按照“先进先出”、“后进后出”的原则来存储数据。
2.队列的应用场景
队列在Java语言环境中是使用频率相当高的数据结构,使用场景非常多的,比如:
- 线程池
- MQ消息队列
- 连接池等
3.队列示例
下面我以ArrayBlockingQueue来举例:
树
树(Tree)是一种典型的非线性结构,它是由 n(n>0)个有限节点组成的一个具有层次关系的集合。
如下图所示:
把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
2.树的种类
树的种类有很多,我们接触到比较多的有如下几种:
哈希表
1.哈希表定义
哈希表,英文名为:Hash表,也称散列表,是根据键值而直接进行访问的数据结构。
2.哈希表数据结构
哈希表的数据结构:本质是数组加哈希函数,如下图所示:
哈希表的特点,大致分为如下3点:
1) 访问速度很快
普通的数据结构中查找某一个关键字通常需要遍历整个数据结构,时间复杂度O(n),而哈希表只需要O(1)的时间级。
2) 可能会产生碰撞
没有完美的散列函数,无论如何总会产生冲突,这时就需要采用冲突解决方案,比如:冲突挂链表,典型的就是HashMap的实现。
3) 散列表无序
散列表还有一个非常明显的特点,那就是无序,为了能够更快地访问元素,散列表是根据散列函数直接找到存储地址的,这样我们的访问速度就能够更快,但是对于有序访问却没有办法应对。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》