什么是链表

维基百科:链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。

为了更好的理解链表,我们拿数组来作对比。

  • 相比数组,链表是一种稍微复杂一点的数据结构。从底层的存储结构上来看:数组需要一块儿连续的内存空间,堆内存的要求比较高,如果我们申请一个100MB大小的数组,当内存中没有连续的、足够大的空间的时候,即便内存的剩余总可用空间大于100MB,仍然会申请失败;而链表恰恰相反,它并不需要一块儿连续的内存空间,它通过“指针”将一组零散的内存块串联起来,所以如果我们申请100MB大小的链表,如果没有100MB连续的内存空间,且内存的剩余总可用空间大于100MB,根本不会有问题。

  • 使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

链表的基本结构如下:

常见的链表结构

链表结构五花八门,但是我们只介绍最常用的三种,分别是:单向链表,单向循环链表,双向循环链表。
(如果你想进一步了解这些结构,可以点击下方的传送门)

链表的优势和劣势

优势
  • 在程序中使用数组之前,必须事先知道数组的大小,增加数组的大小是一个耗时的过程,在运行时几乎不可能扩展数组的大小。而链表不需要提前声明链表的大小,链表的大小是随着使用的过程逐步增大的。
  • 在空间的利用上链表相比数组要更加灵活,不会造成内存的大量浪费。
  • 向链表中插入或从链表中删除一项的操作不需要移动很多项,只涉及常数个节点链的改变,时间复杂度为O(1)。
劣势
  • 由于在链表中,仅仅只有头节点和尾节点是可见的,因此要想查找某个节点,必须从头节点或尾节点一路找下去,时间复杂度至少为O(logn) (二分),不如数组快。

    链表和数组基本操作的时间复杂度对比
    ... 数组 链表
    访问 O(1) O(N)
    搜索 O(N) O(N)
    插入 O(N) O(1)
    删除 O(N) O(1)
  • 实际上,链表插入和删除元素的时间复杂度均为O(N)。为什么呢?因为虽然插入和删除元素的操作是O(1)的没错,但是要想插入或删除节点,你必须得知道节点在哪,获取节点的操作是O(N)的,
    因此总的时间复杂度为O(N)。尽管如此,链表插入删除元素的速度依旧是要优于数组的。

链表的应用场景

链表适合存储对元素查找,访问要求低;但是对删除,插入要求高的数据。

链表-LinkList的更多相关文章

  1. [数据结构]链表LinkList

    目录 1.3 链表 1.3.1 头插法建立单链表 1.3.2 限制链表长度建立单链表 1.3.3 尾插法建立单链表 1.3.4 按序号查找单链表 1.3.5 按值查找单链表 1.3.6 链表的插入 1 ...

  2. Java数据结构与算法(5) - ch05链表(LinkList)

    双端链表与传统链表非常相似,但是它有一个新增的特性:即对最后一个链节点的引用,就像对第一个连接点的引用一样.注意与双向链表进行区别.

  3. [数据结构]链表相关的实现LinkList.cpp

    目录 LinkList.cpp //链表相关操作的实现 LinkList.h LinkListManager.cpp //链表相关实现函数的调用 LinkListManager.h LinkList. ...

  4. C语言----------链表的简单操作

    #include <stdio.h> #include <malloc.h> typedef struct node{ //定义节点类型 char data; //数据域 st ...

  5. C#单链表

    顺序表是用地址连续的存储单元顺序存储线性表中的各个数据元素, 逻辑上相邻的数据元素在物理位置上也相邻.因此,在顺序表中查找任何一个位置上的数据元素非常方便, 这是顺序存储的优点. 但是, 在对顺序表进 ...

  6. 数据结构-------单链表(C++)

    相关信息: /** * @subject 数据结构 实验2 * @author 信管1142班 201411671210 赖俊杰 * @project 单链表 * @time 2015年10月29日1 ...

  7. c-连接两个链表

    概述 还是相对简单,不过要记得释放不用的头结点即可. 代码为: //将lList2头结点连接在lList1尾结点的后面. void combine(linklist lList1, linklist ...

  8. c 单链表反转(不添加新结点空间)

    最近复习考研,加上一直都将"算法"放在很高的位置,所以,蛮重视算法的.不多说了,其实这个问题,不难理解的. 主要代码: //反转单链表. void reverse(linklist ...

  9. C++ 数据结构学习二(单链表)

    模板类 //LinkList.h 单链表#ifndef LINK_LIST_HXX#define LINK_LIST_HXX#include <iostream>using namespa ...

随机推荐

  1. unity之中级工程师

    主要是实际操作. Destroy(游戏对象):会真正销毁游戏对象. 动态链接库 热更新:用户不需要更新整个项目,只需要更新需要更新的部分,使用AssetBundle.PC,Android可以使用逻辑热 ...

  2. js的真值与假值

    假值 结果为 false 的值称为 假值.例如,空字符串 "" 为假值,因为在布尔表达式中,"" 等于 false. false == 0返回:true fal ...

  3. Python 基础 (三)

    字典排序 dict = {'a':1,'c':3,'b':2} 字典没有sort方法,可使用sorted排序,默认通过key排序 dict = sorted(dict),print(dict)key的 ...

  4. UVA-10004-Bicoloring二分图染色

    题意:给一张图,判断是不是二分图: 自己一开始不知道是二分图染色,理解的是任意三点不能互相连接 可能以后遇到这样的模型,可以往二分图想: 首先怎么判定一个图是否为二分图 从其中一个定点开始,将跟它邻接 ...

  5. 2019 Multi-University Training Contest 5

    2019 Multi-University Training Contest 5 A. fraction upsolved 题意 输入 \(x,p\),输出最小的 \(b\) 使得 \(bx\%p&l ...

  6. 实现一个简易版的vuex持久化工具

    背景 最近用uni-app开发小程序项目时,部分需要持久化的内容直接使用vue中的持久化插件貌似不太行,所以想着自己实现一下类似vuex-persistedstate插件的功能,想着功能不多,代码量应 ...

  7. Go语言基础之文件操作

    本文主要介绍了Go语言中文件读写的相关操作. 文件是什么? 计算机中的文件是存储在外部介质(通常是磁盘)上的数据集合,文件分为文本文件和二进制文件. 打开和关闭文件 os.Open()函数能够打开一个 ...

  8. Android Q 正式命名为 Android 10

    根据官方博文,谷歌已经公布了 Android Q 的名称,它并不是想以前一样,以甜食命名,也不是以任何以字母 Q 开头来命名,而是简单称它为 Android 10. 该公司表示,它正在改变其发布版本的 ...

  9. kafka 主题管理

    对于 kafka 主题(topic)的管理(增删改查),使用最多的便是kafka自带的脚本. 创建主题 kafka提供了自带的 kafka-topics 脚本,用来帮助用户创建主题(topic). b ...

  10. Java中 a+=b 和 a=a+b 有什么区别?

    今天舍友突然问我"在java中 a+=b 和a=a+b 有什么区别",说这是一道面试题.当时就不假思索的回答:"一样啊",然后他说有位面试者也回答说一样,所以被 ...