数据结构学习笔记——线性表(中)

线性表的链式存储结构

1、线性表链式存储结构定义

先看个图

线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。这就意味着,这些数据元素可以存在内存未被占用的任意位置

以前的顺序存储结构中,每个数据元素只需要存储数据元素就可以了。现在链式结构中,处理要存储数据元素信息之外,还要存储它的后继元素的存储地址。

为了表示每个元素ai与其直接后继元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需要存储一个指示其直接后继的信息(即直接后继的存储位置)。把存储数据元素的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称作指针或链。这两部分信息组成数据元素ai的存储映像,称为结点。

n个结点链结成一个链表,即为线性表(a1,a2,a3…an)的;链式存储结构,因为此链表的每个结点中只包含一个指针域,所以叫做单链表。

链表的第一个结点存储位置叫做头指针,最后一个结点指针指向NULL。如图:

一般地,我们为了方便,会在单链表的第一个结点前附设一个结点,称为头节点。头节点的数据域可以不存任何数据,也可以存一些线性表的长度等信息。

综上,结点由存放数据元素的数据域和存放后继结点的地址的指针域组成。

2、头指针和头节点的异同

头指针

  • 头指针是指链表指向第一个结点的指针,若链表由头节点,则是指向第一个元素结点的指针;
  • 头指针具有标识作用,所以常用头指针冠以链表的名字;
  • 无论链表是否为空,头指针均不为空。头指针是链表的必要元素。

头结点

  • 头节点是为了操作的统一和方便而设立的,放在第一个元素结点之前,其数据域一般无意义;
  • 有了头节点,对在第一个元素结点前插入结点和删除第一个元素结点,其操作与其他结点的操作就统一了;
  • 头节点不一定是链表的必要元素。

单链表的读取

算法思路:

  1. 声明一个指针p指向链表第一个结点,初始化j从1开始;
  2. 当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
  3. 若到链表末尾p为空,则说明第i个结点不存在;
  4. 否则查找成功,返回结点p的数据。

其核心思想就是工作指针后移。其时间复杂度为O(n)。

单链表的插入和删除

单链表的插入

看图说话

算法思路:

  1. 声明一指针p指向链表头节点,初始化j从1开始;
  2. 当j < i 时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
  3. 若到链表末尾p为空,则说明第i个结点不存在;
  4. 否则查找成功,在系统中生成一个空结点s;
  5. 将数据元素e赋值给 s->data;
  6. 单链表的插入标准语句 s->next; p->next=s;
  7. 返回成功。

单链表的删除

上图

算法思路:

  1. 声明一指针p指向链表的头指针,初始化j从1开始;
  2. 当j< i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
  3. 若到链表末尾p为空,则说明第i个结点不存在;
  4. 否则查找成功,将欲删除的结点p->next赋值给q;
  5. 单链表的删除标准语句 p->next=q->next;
  6. 将q结点中的数据赋值给e,作为返回;
  7. 释放q结点;
  8. 返回成功。

从整个算法来说,单链表的删除和插入的时间复杂度都是O(n)。

显然,对于插入或删除数据越频繁的操作,单链表的效率优势就越明显。

单链表的整表创建

顺序存储结构的创建,其实就是一个数组的初始化,即声明一个类型和大小的数组并赋值的过程。

对于单链表来说,它所占用的空间的大小和位置是不需要预先分配划定的,可以根据系统情况即时生效。

算法思路:

  1. 声明一指针p和计数器变量i;
  2. 初始化一空链表L;
  3. 让L的头节点的指针指向NULL,即建立一个带头节点的单链表;
  4. 循环: 生成一新结点赋值给p; 随机生成一个数字赋值给p的数据域p->data; 将p插入到头节点与前一新结点之间。

以上思路称作头插法,当然对应还有尾插法,不再累赘。

单链表的整表删除

算法思路:

  1. 声明一结点p和q;
  2. 将第一个结点赋值给p;
  3. 循环: 将下一节点赋值给q; 释放p; 将q赋值给p。

两种结构优缺点

存储分配方式

  • 顺序存储结构用一段来内需的存储单元依次存储线性表的数据元素;
  • 单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素;

时间性能

a、查找 顺序存储结构O(1) 单链表O(n)

b、插入和删除 顺序存储结构需要平均移动表长一般的元素,时间为O(n) 单链表在选出某位置的指针后,插入和删除的时间仅为O(1)

空间性能

  • 顺序存储结构需要预分配存储空间,分大了,浪费,分小了易发生上溢;
  • 单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。

总结来说:

  • 顺序结构查找快,增删慢;
  • 链表 查找慢,增删快;
  • 元素个数不大或根本不变或事先知道其最大容量时,可以采用顺序存储结构;
  • 当元素变化大或根本不知道多大,应采用链表,不考虑内存空间大小的问题。

原文发布于微信公众号 - Android机动车(JsAndroidClub)

原文发表时间:2018-03-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏自学笔记

Data Structurestackheapheap的实现索引堆tree并查集图 Graph

堆的基本性质: ①堆中的某一个节点总是不小于或不大于其父节点的值。 ②堆总是一棵完全二叉树 比较经典的堆有二叉堆,费波纳茨堆等等。如果一棵二叉树最下层上的...

10430
来自专栏数据结构与算法

2879 堆的判断

2879 堆的判断 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 堆是一种常用...

32680
来自专栏大闲人柴毛毛

贪心算法(五)——迪杰斯特拉算法

问题描述 给一个有向无环带权图,并给一个起点,求出该原点到所有顶点的最短路径。 ? 数据结构 dis: Map<String,Integer> dis; ...

41790
来自专栏java系列博客

Java ConcurrentModificationException异常原因和解决方法

87220
来自专栏weixuqin 的专栏

数据结构学习笔记(线性表)

31350
来自专栏Java帮帮-微信公众号-技术文章全总结

HashSet 源码分析【面试+工作】

在工作中,经常有这样的需求,需要判断某个ID是否在某个组的管理之下等,就需要查询该组下的ID放到一个集合中,且集合中元素不能有重复,之后判断该集合是否包含我们的...

12630
来自专栏用户画像

6.2.2 折半查找

折半查找,又称二分查找,它适用于有序的顺序表。基本思路是:首先将给定值key与表中中间位置元素的关键字比较,若相等,则查找成功,返回该元素的存储位置;若不等,则...

7310
来自专栏腾讯IVWEB团队的专栏

ES6 中的 Set

ES6 新增了几种集合类型,本文主要介绍Set以及其使用。Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的...

84900
来自专栏Java爬坑系列

【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解

  今天来介绍一下容器类中的另一个哈希表———》LinkedHashMap。这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap...

9220
来自专栏张俊红

数据结构—线性表

本篇开始,又会开始一个新的系列,数据结构,数据结构在算法或者是编程中的重要性不言而喻,所以学好数据结构还是很有必要的。本篇主要介绍数据结构的第一个结构——线性表...

14130

扫码关注云+社区

领取腾讯云代金券