300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 数组是逻辑结构还是存储结构_数据结构之存储方式

数组是逻辑结构还是存储结构_数据结构之存储方式

时间:2022-11-04 11:54:08

相关推荐

数组是逻辑结构还是存储结构_数据结构之存储方式

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

这句话怎么理解,不是还有散列表、栈、队列、堆、树、图等等各种数据结构吗?

我们分析问题,⼀定要有递归的思想,⾃顶向下,从抽象到具体。你上来就列出这么多,那些都属于「上层建筑」,⽽数组和链表才是「结构基础」。因为那些多样化的数据结构,究其源头,都是在链表或者数组上的特殊操作,API不同⽽已。

⽐如说「栈」、「队列」这两种数据结构既可以使⽤链表也可以使⽤数组实现。⽤数组实现,就要处理扩容缩容的问题;⽤链表实现,没有这个问题,但需要更多的内存空间存储节点指针。

栈(Stack)。撤回,即 Ctrl+Z,是我们最常见的操作之一,大多数应用都会支持这个功能。你知道它是怎么实现的吗?答案是这样的:把之前的应用状态(限制个数)保存到内存中,最近的状态放到第一个。这时,我们需要栈(Stack)来实现这个功能。栈中的元素采用 LIFO (Last In First Out),即后进先出。

队列(Queue)与栈类似,都是采用线性结构存储数据。它们的区别在于,栈采用 LIFO 方式,而队列采用先进先出,即FIFO(First in First Out)。

队列

图(Graph)的两种表⽰⽅法,邻接表就是链表,邻接矩阵就是⼆维数组。邻接矩阵判断连通性迅速,并可以进⾏矩阵运算解决⼀些问题,但是如果图⽐较稀疏的话很耗费空间。邻接表⽐较节省空间,但是很多操作的效率上肯定⽐不过邻接矩阵。

散列表(Hash)就是哈希表,通过散列函数把键映射到⼀个⼤数组⾥。⽽且对于解决散列冲突的⽅法,拉链法需要链表特性,操作简单,但需要额外的空间存储指针;线性探查法就需要数组特性,以便连续寻址,不需要指针的存储空间,但操作稍微复杂些。

散列表(哈希表)

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

前缀树(Prefix Trees 或者 Trie)与树类似,用于处理字符串相关的问题时非常高效。它可以实现快速检索,常用于字典中的单词查询,搜索引擎的自动补全甚至 IP 路由。

前缀树

了解Redis数据库的朋友可能也知道,Redis提供列表、字符串、集合等等⼏种常⽤数据结构,但是对于每种数据结构,底层的存储⽅式都⾄少有两种,以便于根据存储数据的实际情况使⽤合适的存储⽅式。

综上,数据结构种类很多,甚⾄你也可以发明⾃⼰的数据结构,但是底层存储⽆⾮数组或者链表,⼆者的优缺点如下:

数组由于是紧凑连续存储,可以随机访问,通过索引快速找到对应元素,⽽且相对节约存储空间。但正因为连续存储,内存空间必须⼀次性分配够,所以说数组如果要扩容,需要重新分配⼀块更⼤的空间,再把数据全部复制过去,时间复杂度O(N);⽽且你如果想在数组中间进⾏插⼊和删除,每次必须搬移后⾯的所有数据以保持连续,时间复杂度O(N)。

数组

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

链表

第一次在知乎写文章哈,如有不足,敬请指正!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。