1 前言
前面的博客中,笔者提到了顺序表,现在又出来个链表?两者是什么关系呢?其实他们均属于线性表!
有了宏观的概念之后,我们详细来聊聊链表具体的情况!
2 什么是链表?
定义:
- 链表(Linked list)是一种常见的基础数据结构,是一种线性表
- 但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。见下图:
所以说链表的一个节点包括两部分信息: - 数据区。用来存储数据
- 地址区(链接区):用来指向下一个节点
- 变量p:链表的头节点(首节点)的位置。从p出发能找到表中的任意节点。
3 链表的分类
具体来说,链表有下面三种形式:单向链表;双向链表;单向循环链表
- 单向链表
- 单向链表也叫单链表,是链表中最简单的一种形式
- 每个节点包含两个区域,一个数据区和一个地址区(链接区)
- 当前节点的链接指向链表中的下一个节点,最后一个节点的链接区指向None。
- 双向链表
- 也叫双面链表。
- 【双指向+首尾前后指向None】每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
- 单向循环链表
- 单向链表的一种变形。链表中最后一个节点的next域不再为None,而是指向链表的头节点。
- 单向链表的一种变形。链表中最后一个节点的next域不再为None,而是指向链表的头节点。
4 顺序表和链表之间的联系和区别
首先上一个很好的表格:
顺序表和链表在不同操作时对应的时间复杂度见下表:
解释一波:
- 访问元素:
- 链表:从头结点开始依次访问元素,故为O(n)
- 顺序表:直接可以定位到元素所在地址!故为O(1)
- 头部插入/删除:
- 链表:直接删除,只需改变指向即可,局部操作,故为O(1)
- 顺序表:删除头部元素之后,后面所有元素都要往前移动一位!插入即往后移动!故为O(n)
- 尾部插入/删除:
- 链表:从头结点开始依次访问到最后一个元素,然后删除或者插入,全局操作,故为O(n)
- 顺序表:尾部直接添加或者删除即可,前面的元素不需要动!故为O(1)
- 中间插入/删除:
- 链表:从头结点开始依次访问到给定位置,然后删除或者插入,再改变链接区指向,全局操作,故为O(n)
- 顺序表:中间插入或者删除,都需要改变后面所有的元素,要么往后移动要么前移!故为O(n)
- 虽然此时两者时间复杂度一样,但是所花时间的侧重点不同,链表主要时间消耗在依次访问元素,即遍历,顺序表主要时间消耗在数据的整体移动迁移。
结合上面时间复杂度的相关对比,链表和顺序表究竟有什么联系和区别呢?
1、联系
- 都属于线性表,用来存储数据。
2、区别
- 操作对应的时间复杂度不同。除了在中间插入/删除元素之外,链表和顺序表的时间复杂度不同。【可以拆成几点来说】
- 存储数据的方式不同。顺序表将元素顺序地存放在一块连续的存储区里;而链表是将元素存放在通过链接构造起来的一系列存储块中,分散的。
- 空间的利用不同。链表增加了结点的链接区,空间开销比较大,但对存储空间的使用要相对灵活。