【考研数据结构——C语言描述】第二章 线性表顺序存储结构上的基本操作——线性表的链式表示

25计算机考研,数据结构知识点整理(内容借鉴了王道408+数据结构教材),还会不断完善所整理的内容,后续的内容也会不断更新(可以关注),若有错误和不足欢迎各位朋友指出!

链式存储是最常用的动态存储方法。为了克服顺序表的缺点可以采用链式存储。通常将采用链式存储结构的线性表称为线性链表。从链接方式的角度,链表可分为单链表循环链双链表;从实现方式角度,链表可分为动态链表静态链表

一.单链表的定义

(1)在顺序表中是用一组地址连续的存储单元来依次存放线性表的结点,因此结点的逻辑顺序和物理顺序是一致的。而链表则是用一组任意的存储单元来存放线性表的结点,这组存储单元可以是连续的,也可以是非连续的,甚至是零散分布在内存的任何位置上。因此,链表中结点的逻辑顺序和物理顺序不一定相同。为了正确地表示结点间的逻辑关系,必须在存储线性表的每个数据元素值的同时,存储指示其后继结点的地址(或位置)信息,这两部分信息组成的存储映像称为链表的结点(node)

(2)线性链表正是通过每个结点的指针域将几个结点按逻辑顺序链接在一起。每个结点只有一个 next 指针域的链表称为单链表(线性表的链式存储),它是指通过一组任意的存储单元来存储线性表中的数据元素。

(3)为了建立数据元素之间的线性关系,对每个链表结点(包含两部分),除存放元素自身的信息之外,还需要存放一个指向其后继的指针。单链表结点结构如图2.3所示,其中data数据域存放数据元素next指针域存放其后继结点的地址

 单链表中结点类型的描述如下:

typedef struct LNode{  //定义单链表结点类型
   ElemType data; //数据域
   struct LNode *next; //指针域
}LNode, *LinkList; //*LinkList为结构指针类型

(3)头指针通常用头指针L(或H、head等)来标识一个单链表(单链表中每个结点的存储地址存放在其前驱结点的指针域中,线性表中第一个结点无前驱),指出链表的起始地址,头指针为NULL时表示一个空表。由于线性表的最后一个结点没有直接后继,则指定单链表的最后一个结点的指针域为“空”( NULL)(用^表示)。单链表的头指针标示着整个单链表的开始,习惯上用头指针代表单链表,单链表由头指针唯一确定,故单链表可以用头指针命名。

(4)头结点为了操作上的方便,在单链表第一个数据结点之前附加一个结点,称为头结点。头结点的数据域可以不设任何信息,但也可以记录表长等信息。

头结点与头指针的关系:

不管带不带头结点,头指针都始终指向链表的第一个结点,而头结点是带头结点的链表中的第一个结点,结点内通常不存储信息。

引入头结点后,可以带来两个优点:
①由于第一个数据结点的位置被存放在头结点的指针域中,因此在链表的第一个位置上的操作和在表的其他位置上的操作一致,无须进行特殊处理。

②无论链表是否为空,其头指针都是指向头结点的非空指针(空表中头结点的指针域为空),因此空表和非空表的处理也就得到了统一。

(5)首元节点链表中存储第一个数据元素的节点

给定单链表的头指针H,即可顺着每个结点的next指针域得到单链表中的每个元素。因此对于整个单链表的操作必须从头指针开始例如,图2.6所示为线性表(A,B,C,D,E,F,G,H)的单链表存储结构,整个单链表的操作需从头指针H开始进行,顺着每个结点的指针域依次找到线性表的各个元素。
一般情况下,使用链表只关心链表中结点间的逻辑顺序,并不关心每个结点的实际存储位置,因此通常用箭头来表示链域中的指针,于是链表就可以更直观地画成用箭头链接起来的结点序列。图2.6单链表示例可表示为图2.7所示的逻辑状态

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 插入元素:1. 找到要插入的位置; 2. 将该位置及其后面的元素以步长为1向后移动; 3. 将新元素插入到该位置上。删除元素:1. 找到要删除的位置; 2. 将该位置及其后面的元素以步长为1向前移动; 3. 将最后一个元素删除。 ### 回答2: 线性表顺序存储结构上的插入元素和删除元素运算可以通过C语言代码实现。 插入元素操作可以包括以下步骤: 1. 先判断线性表是否已满,若已满则无法插入新元素。 2. 若线性表未满,则需要移动插入位置之后的元素,为新元素腾出位置。 3. 将新元素插入到指定位置。 以下是C语言代码示例: ``` #include <stdio.h> #define MAX_SIZE 100 // 定义线性表的最大长度 // 定义顺序存储结构线性表 typedef struct { int data[MAX_SIZE]; int length; } SeqList; // 插入元素操作 int insert(SeqList *list, int position, int element) { if (list->length >= MAX_SIZE) { printf("线性表已满,无法插入新元素。\n"); return -1; } if (position < 1 || position > list->length + 1) { printf("插入位置不合法。\n"); return -1; } // 移动插入位置之后的元素 for (int i = list->length; i >= position; i--) { list->data[i] = list->data[i - 1]; } // 插入新元素 list->data[position - 1] = element; list->length++; return 0; } int main() { SeqList list; list.length = 0; // 插入元素 insert(&list, 1, 10); // 在第1个位置插入元素10 insert(&list, 2, 20); // 在第2个位置插入元素20 for (int i = 0; i < list.length; i++) { printf("%d ", list.data[i]); } printf("\n"); return 0; } ``` 删除元素操作可以包括以下步骤: 1. 先判断线性表是否为空,若为空则无法删除元素。 2. 若线性表非空,则需要移动删除位置之后的元素,覆盖被删除的元素位置。 3. 更新线性表的长度。 以下是C语言代码示例: ``` #include <stdio.h> #define MAX_SIZE 100 // 定义线性表的最大长度 // 定义顺序存储结构线性表 typedef struct { int data[MAX_SIZE]; int length; } SeqList; // 删除元素操作 int remove(SeqList *list, int position) { if (list->length == 0) { printf("线性表为空,无法删除元素。\n"); return -1; } if (position < 1 || position > list->length) { printf("删除位置不合法。\n"); return -1; } // 移动删除位置之后的元素 for (int i = position - 1; i < list->length - 1; i++) { list->data[i] = list->data[i + 1]; } list->length--; return 0; } int main() { SeqList list; list.length = 0; // 插入元素 list.data[0] = 10; list.length++; list.data[1] = 20; list.length++; // 删除元素 remove(&list, 1); // 删除第1个位置的元素 for (int i = 0; i < list.length; i++) { printf("%d ", list.data[i]); } printf("\n"); return 0; } ``` 希望以上代码示例可以帮助到您理解如何在C语言表示线性表顺序存储结构上的插入元素和删除元素运算。 ### 回答3: 线性表顺序存储结构上的插入元素操作: 1. 首先需要定义一个顺序存储结构线性表,其中包括一个数组用于存储元素,以及一个变量用于记录线性表的长度。 ``` #define MAX_SIZE 100 // 定义线性表的最大容量 typedef struct { int data[MAX_SIZE]; // 用于存储元素的数组 int length; // 表示线性表的长度 } SeqList; ``` 2. 插入元素操作需要指定插入位置以及待插入的元素值。首先需要判断插入位置的合法性,即位置是否在有效范围内。如果合法,则将插入位置之后的所有元素向后移动一位,然后将待插入元素放入插入位置处,最后更新线性表的长度。 ``` void Insert(SeqList *list, int position, int element) { // 判断插入位置的合法性 if (position < 1 || position > list->length + 1) { printf("插入位置不合法!"); return; } // 从插入位置开始,将后面的元素向后移动一位 for (int i = list->length; i >= position; i--) { list->data[i] = list->data[i - 1]; } // 将待插入元素放入插入位置 list->data[position - 1] = element; // 更新线性表的长度 list->length++; } ``` 线性表顺序存储结构上的删除元素操作: 1. 删除元素操作需要指定要删除的位置。首先需要判断删除位置的合法性,即位置是否在有效范围内。如果合法,则将删除位置之后的所有元素向前移动一位,最后更新线性表的长度。 ``` void Delete(SeqList *list, int position) { // 判断删除位置的合法性 if (position < 1 || position > list->length) { printf("删除位置不合法!"); return; } // 从删除位置开始,将后面的元素向前移动一位 for (int i = position - 1; i < list->length - 1; i++) { list->data[i] = list->data[i + 1]; } // 更新线性表的长度 list->length--; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值