链表、堆栈、数组、队列
2018-06-01 本文已影响72人
什锦甜
队列、堆栈、链表和数组这些概念傻傻分不清楚,经过查阅资料稍微总结了一下。
数据结构:描述数据元素逻辑关系的集合。队列就是一种先进先出的逻辑结构,栈是一种先进后出的逻辑结构,家谱是一种树形的逻辑结构!数组、链表、堆栈和队列是最基本的数据结构。
数据存储结构:描述数据在计算机中存储方式。常见的有两种:顺序存储,非顺序存储。数组就是顺序存储,数据存储的地址是连续的;链表是非顺序存储,数据存储的地址是不连续的。
-
队列:队列的特点是先入先出 (FIFO) ,可以使用数组和链表来实现。
图1.1 队列
队列只允许在队尾添加数据,在队头删除数据。但是可以查看队头和队尾的数据。还有一种是双端队列,在两端都可以插入和删除:
图1.2 双端队列 -
堆栈:这里讨论的是数据结构中的堆(heap)和栈(stack),而不是内存中的堆栈。栈:是一种连续存储的数据结构,特点是存储的数据先进后出(FILO)。可以使用数组和链表来实现。
图2.1 栈
堆:是一棵完全二叉树结构,特点是父节点的值大于(小于)两个子节点的值(分别称为最大堆和最小堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。
-
链表: 链表是在非连续的内存单元中保存数据,并且通过指针将各个内存单元链接在一起,最右一个节点的指针指向 NULL 。链表不需要提前分配固定大小存储空间,当需要存储数据的时候分配一块内存并将这块内存插入链表中。
图3.1 链表结构
在链表中查找第 n 个数据以及查找指定的数据的时间复杂度是 O(N) ,但是插入和删除数据的时间复杂度是 O(1) ,因为只需要调整指针就可以:
图3.2 添加元素
图3.3 删除元素
向上面这样的链表结构在插入和删除的时候编程会比较困难,因为需要记住当前节点的前一个节点,这样才能完成插入和删除。为了简便通常使用带有头节点的链表:
图3.4 带有头节点的单链表
上面的链表是单链表,此外还有双链表,就是节点中包含指向下一个节点的指针和指向上一个节点的指针:
图3.5 双向链表
不带有头节点的双向链表在插入和删除数据的时候也不会出现单链表那样的问题。此外还有一种链表是循环链表,它是将双向链表的头尾相接:
图3.6 双向循环链表
向循环双向链表和循环链表中插入或者从中删除数据只是多移动几个指针。 -
数组: 组是使用一块连续的内存空间保存数据,保存的数据的个数在分配内存的时候就是确定的。
在数组中访问数组中第 n 个数据的时间花费是 O(1) ,查找一个指定的数据则是 O(N)。当向数组中插入或者删除数据的时候,最好的情况是在数组的末尾进行操作,时间复杂度是O(1) ,但是最坏情况是插入或者删除第一个数据,时间复杂度是 O(N) 。在任意位置插入或者删除数据的时候,后面的数据全部需要移动,移动的数据还是和数据个数有关所以总体的时间复杂度仍然是 O(N) 。
图4.1 数组插入元素