天天看点

数据结构的存储方式

说到数据结构,我们可能会想到各种各样的数据结构:如果栈,队列,树,图,散列表,再高级一些,可能学过堆,优先队列,线段树,并查集和AVL树,红黑树等。上面说的数据结构,基本上都可以使用数组或链表两种存储方式来实现的。

数据结构的存储方式只有两种:数组(顺序存储结构)和链表(链式存储结构)。

数组和链表是数据结构存储数据的方式,而栈堆树图等数据结构是在使用数组和链表存储数据的基础上,对数据相关操作进行规则的约束和定义,究其源头,都是在数组或者链表上进行特殊操作,API不同而已。

比如说“队列”,“栈”,队列约束数据先进先出,栈约束数据先进后出,这两种数据结构既可以使用链表也可以使用数组来实现,对应实现不同的api而已,使用数组,需要处理数据移动和扩容缩容的问题;使用链表需要更多的内存空间来存储指向节点的指针。

数据结构的存储方式

栈和队列

“图”主要有两种实现方式,邻接表和邻接矩阵,其中邻接表是链表实现的,邻接矩阵是二维数组实现的。邻接矩阵判断连通性更适合,可以进行矩阵运算解决一些问题,但如果数据稀疏的话,就好浪费内存空间了。邻接表比较节省空间,但是操作效率上肯定比不上邻接矩阵。

数据结构的存储方式

“散列表”是通过散列函数把键值对映射到一个大的数组中,可以使用拉链法解决数据冲突,拉链法底层使用的是链表的特性,java中的HashMap就是这样实现的,即使用了数组,也使用链表解决冲突。

数据结构的存储方式

散列表

“树”, 可以⽤数组实现,比如“堆”,因为「堆」是⼀个完全⼆叉树,⽤数组存 储不需要节点指针,操作也比较简单;⽤链表实现就是很常⻅的那种 「树」,因为不⼀定是完全⼆叉树,所以不适合⽤数组存储。为此,在这种 链表「树」结构之上,⼜衍⽣出各种巧妙的设计,⽐如⼆叉搜索树、AVL 树、红⿊树、区间树、B 树等等,以应对不同的问题。

数据结构的存储方式

数据结构种类有很多,甚至你可以定义自己的数据结构,但是底层的存储方式无非就是数组或者链表。

“数组” 底层连续存储,可以随机访问,能够通过索引快速找到对应元素,所以当索引具有业务含义的时候,根据索引能够实现O(1)时间复杂度的查询。但正因为连续存储,内存空间必须⼀次性分配够,所 以说数组如果要扩容,需要重新分配⼀块更⼤的空间,再把数据全部复制过 去,时间复杂度 O(N);⽽且你如果想在数组中间进⾏插⼊和删除,每次必 须搬移后⾯的所有数据以保持连续,时间复杂度 O(N)。

“链表” 每存入一个元素,需要申请内存空间,所以链表是不连续的,是靠指针指向下⼀个元素的位置,所以不存在扩容问题;如果知道某⼀元素的前驱和后驱,操作指针即可删除该元素或 者插⼊新元素,时间复杂度 O(1)。但是正因为存储空间不连续,你⽆法根 据⼀个索引算出对应元素的地址,所以不能随机访问,查询数据需要遍历访问,时间复杂度为O(n);⽽且由于每个元素必 须存储指向前后元素位置的指针,会消耗相对更多的储存空间。

基本上现在的大厂面试,算法是肯定要考的,每次想冲击大厂,想到自己的算法都会觉得很无奈。算法的学习是持之以恒的,不是一蹴而就得,所以打算最近要持续学习数据结构和算法。这里我主要阅读了labuladong的算法小抄,觉得写的非常好,大家可以去关注一下,在这里说明一下,归纳总结一下自己学习心得。

继续阅读