大话数据结构 第三章 线性表(一) 顺序存储结构和单链表

线性表的定义

  • 线性表指:零个或多个数据元素的有限序列
  • 线性表元素的个数n定义为线性表的长度,n=0是被称为空表
  • 在较复杂的线性表中,一个数据元素可以由若干个数据项组成

顺序存储结构

  • 线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素
  • 一般使用一维数组实现
  • 三个属性:起始位置、最大存储容量、当前长度

地址计算方法

  • 第i个元素的位置 = 首元素的地址 + (i-1)* 单个元素所占用的存储单元
  • 不论元素的位置,顺序存储的存取时间都是一样的,性能为O(1),这种存储结构称为随机存取结构

插入操作思路

  • 如果插入位置不合理,抛出异常;
  • 如果线性表长度大于数组长度,则抛出异常或者动态增加容量;
  • 从最后一个元素开始向前遍历到第i个位置,分别都将它们向后移动一个位置;
  • 将要插入的元素填入位置i处;
  • 表长加1

删除操作思路

  • 如果删除位置不合理,抛出异常;
  • 取出删除元素;
  • 从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置
  • 表长减1

插入和删除的时间复杂度

  • 在存、读时,时间复杂度都是O(1);
  • 在插入、删除时,时间复杂度都是O(n)

顺序存储结构的优缺点

优点

  • 无须为表示表中元素的逻辑关系而增加额外的存储空间(无须存储地址指针)
  • 可以快速地存取表中任一位置的元素

缺点

  • 插入和删除操作需要移动大量元素
  • 当线性表长度变化较大时,难以确定存储空间的容量
  • 造成存储空间的“碎片”

链式存储结构(单链表)

  • 链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。在链式结构中,除了要存储数据的元素信息外,还要存储它后继元素的存储地址
  • 数据域:存储数据元素信息的域
  • 指针域:存储直接后继位置信息的域
  • 结点 = 数据域 + 指针域
  • 单链表:每个结点中只包含一个指针域

头指针与头结点

  • 头指针:链表中第一个结点的存储位置。整个链表的存取必须从头指针开始进行
  • 头结点:为了更方便对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头结点。头结点的指针域存储头指针。
  • 头指针必需,头结点非必需。

读取操作

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

插入操作

  • 只需将结点s插入到结点p和结点p->next之中
  • 具体操作:s->next = p->next; p->next = s;
  • 注意不能颠倒

删除操作

  • 欲删除结点q,只需将它的前继结点的指针绕过,指向它的后继结点即可。即:把p的后继结点改成p的后继的后继结点
  • 具体操作:q = p->next; p->next = q->next;

插入和删除的时间复杂度

  • 查找和删除都是由两部分组成:1.遍历查找第i个结点;2.插入和删除结点
  • 顺序存储结构每次插入和删除的时间复杂度都是O(n);而单链表的第一次插入和删除复杂度为O(n),后续的操作复杂度都是O(1)

整表创建

头插法

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

尾插法

  • 前面的步骤和头插法类似
  • 将表尾终端结点的指针指向新结点:r->next = p;
  • 将当前的新结点定义为表尾终端结点:r = p;
  • 在结束时,将r-> next = NULL;

整表删除

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

单链表结构和顺序存储结构的优缺点

存储分配方式

  • 顺序存储方式:用一段连续的存储单元依次存储线性表的数据元素
  • 单链表:采用链式存储结构,用一组任意的存储单元存放线性表的元素

时间性能

查找

  • 顺序存储结构O(1)、单链表O(n)

插入和删除

  • 顺序存储结构O(n)、单链表O(1)(在线出某位置的指针之后)

空间性能

  • 顺序存储结构:需要预分配内存,容易产生浪费或溢出
  • 单链表:不需要分配内存,元素个数也不受限制

检验性的结论

  • 若线性表需要频繁查找,很少进行插入和删除时,宜采用顺序存储结构;若需要频繁插入和删除时,采用单链表结构
  • 元素个数变化较大或者根本不知道有多大时,最好使用单链表结构
发布了59 篇原创文章 · 获赞 3 · 访问量 1809

猜你喜欢

转载自blog.csdn.net/Felix_hyfy/article/details/98876629