4.线性表的循环链表、双向链表、以及应用
创始人
2025-06-01 08:28:14

数据结构很重要!

数据结构很重要!!!

数据结构很重要!!!!

思考

1.线性表的链式表示和实现内容?(What)

2.为什么需要线性表的链式表示和实现?(Why)

3.如何学好线性表的链式表示和实现?(How)

注:特别感谢青岛大学王卓老师

第3章 栈和队列.pdf

一.线性表的链式表示和实现内容?(What)

总体内容概览:思维导图

1.链式存储结构定义:

结点存储位置是任意的,逻辑上位置跟物理上位置不同。

线性表的链式表示又称为非顺序映像链式映像

用一组任意的存储单元,来存放线性表的数据元素。

这组存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上

2.例子:线性表(赵、钱、孙、李)

链表: 结点

存储地址 数据域 指针域

0112 李涵 0053

单链表:由头指针唯一确定,因此单链表可以用头指针的名字来命令。

3.例子:26个英文小写字母表的链式存储结构

逻辑结构:(a,b,c,d,....,z)

链式存储结构:head(头指针)->{数据域1,指针域1}->{数据域2,指针域2}->{..........}

数据域:存储元素数值数据

指针域:存储直接后继结点的存储位置

4.链式存储术语

结点:数据元素的存储映像

链表:n个结点由指针链接在一起组成一个链表。

5.单链表、双链表、循环链表

单链表:结点只有一个指针域的链表

双链表:结点有俩个指针域的链表。

循环链表:首尾相接的链表称为循环链表

6.头指针、头结点、首元结点

头指针:是指向链表中第一个结点的指针。

首元结点:链表中存储第一个数据元素a1的结点。

头结点:首元结点之前附设的一个结点。

7.不带头结点、带头结点

讨论1:如何表示空表?

无头结点:头指针为空时表述空表

有头结点:当头结点的指针域为空时表示空表

讨论2:在链表中设置头结点有什么好处?

有了头结点和后面首元结点处理是一样的。

讨论3:头结点的数据域内装的是什么?

头结点的数据域可以为空,也可以存放线性表长度。

头结点,不计入链表长度值。

8.链表特点

链表:顺序存储、逻辑位置和存储位置不一定相邻。

访问时只能通过头指针进入链表。然后通过每个结点的指针域依次向后顺序扫描其余结点。

顺序表:随机存取、逻辑位置和存储位置相邻。

9.单链表的定义和表示

单链表是:由表头唯一确定。

Lnode:结点。

Lnode a ; //定义一个节点a

a.data a.next

LinkList L; //L就是节点的一个指针

LNode *p 《==等价于==》LinkList L ;

10.单链表操作

1.单链表的初始化

  1. 分配内存空间
  2. L地址指向分配空间
  3. L->next = Null;

2.判断链表是否为空

空链表:链表中无元素

判断:头结点的指针域是否为空

int ListEmpty(LinkList L){

if(L->next) //非空

return 0;

else

return 1;

}

3.单链表的销毁

销毁:需要删除一个个节点(包括删除头结点、头指针)

  1. 头指针L指向头结点
  2. p指针 = L
  3. L=L->next;
  4. delete p (C++写法)

status DestroyList_L(LinkList &L){

Lnode *p;

while(L){

p=L;

L=L->next;

delete p;

}

}

4.清空链表

清空链表:头结点的指针域为空(头指针和头结点都在),清空其他元素。

status ClearList(LinkList &L){

Lnode *p,*q;

p=L->next;

while(p){

q=p->next;

delete p;

p=q;

}

L->next = Null;

return ok;

}

5.求单链表的表长

p=L->next

p=p->next

int ListLength(LinkList L){

LinkList p;

p=L->next;

int i=0;

while(p){

i++;

p=p->next;

}

return i;

}

6.知识回顾

1.单链表的销毁

statu Destory(LinkList &L){

Lnode *p;

while(L){

p=L;

L=L->next;

delete p;

}

return ok;

}

2.清空单链表

status ClearList(LinkList &L){

Lnode *p,*q;

p=L->next;

while(p){

q=p->next;

delete p;

p=q;

}

L->next=Null;

return ok;

}

3.求单链表的表长

int ListLength(LinkList L){

int i = 0 ;

Lnode *p;

p=L->next;

while(p){

i++;

p=p->next;

}

return i;

}

4.判断链表是否为空

status LinkListEmpty(LinkList L){

Lnode *p;

p=L->next;

if(p) return 1;

else return 0;

}

7.取值-取单链表中第i个元素

int GetElem(LinkList L,int i,ElemType &e){

Lnode *p;

p=L->next;

int j=1;

if(p&&j

p=p->next;

j++;

}

if(!p||j>i) return error;

e=p->data;

return e;

}

8.按值查找-根据指定数据获取该数据所在的位置(地址)

int LocalElem(LinkList L, Elem e){

Lnode *p;

p=L->next;

int i =1;

if(p&&p->data!==e){

p=p->next;

i++;

}

if(!p) return 0;

return i;

}

9.插入-在第i个节点前插入值为e的新节点

Status ListInsert(LinkList &L,int i,ElemType e){

Lnode *p;

p=L; j=0;

while(p||j

p=p->next;

++j;

}

if(!p||j>i-1) return error;

s=new Lnode ; s->data = e;

s->next=p->next;

p->next = s;

return ok;

}

10.删除-删除第i个节点

Status ListDelete_L(LinkList &L,int i,ElemType &e){

Lnode *p,*q;

p=L, j=0;

if(!p->next&&j

p=p->next;

++j;

}

q=p->next;

p->next=q->next;

e=q->data;

delete q;

return ok;

}

11.单链表的查找、插入、删除算法时间效率分析

1.查找:O(n)

2.插入、删除:O(1)

12.单链表:头插法

void CreateList_H(LinkList &L,int n){

L=new LNode;

L->next=Null;

for(i=n;i>0;--i){

p=new LNode;

scanf(&p->data);

p->next=L->next;

L->next=p;

}

}

13.单链表:尾插法

void CreateList_R(LinkList &L,int n){

L=new LNode;

r=L;

for(i=0;i

p=new LNode;

scanf(p->data);

p->next=null;

r->next=p;

r=p;

}

}

二.为什么需要线性表的链式表示和实现?(Why)

1.顺序表的优缺点?

1.顺序表的优点:任意元素均可随机存取。

2.顺训表的缺点:进行插入和删除操作时,需要移动大量的元素,存储空间不灵活。

3.顺序表的特点:以物理位置相邻表示逻辑关系。

2.链表的优缺点?

1.链表优点插入、删除所耗费的时间复杂度为O(1),从头查找前驱结点消耗时间复杂度为O(n)。

2.链表缺点:只能顺序存取,查找时间为O(n)

3.链表的特点:逻辑上位置跟物理位置不一样,结点是任意存储的。

3.链表分几类?

  1. 单链表:结点只有一个指针域的链表
  2. 双链表:结点有俩个指针域的链表
  3. 循环链表:首尾相接的链表。

4.设置头结点有什么好处?

有了头结点,和后面处理首元结点是一样的。

5.单链表的定义?

单链表:由表头唯一确定。

存储结构:

typedef struct Lnode{

int data;

struct Lnode *next;

}Lnode,*LinkList

6.单链表操作(13种)

1.单链表的初始化

1.分配内存空间

2.L指向分配空间

3.L->next=Null

Status initList(LinkList L){

L=(LinkList)malloc(sizeof(Lnode));

L->next=Null;

}

2.判断链表是否为空

int emptyList(LinkList L){

if(L->next==null){

return 1; //为空

}else{

return 0;

}

}

3.单链表的销毁

销毁:需要删除一个个结点(包括头结点、头指针)

算法:从头指针开始,依次释放所有结点

status destoryList(LinkList &L){

Lnode *p;

while(L){

p=L;

L=L->next;

delete p;

}

}

4.清空单链表

头结点的指针域为空(头指针和头结点都在),删除其他元素

status CleanList(LinkList &L){

Lnode *p ,*q;

p=L->next;

while(p){

q=p->next;

delete p;

p=q;

}

L->next=Null;

return ok;

}

5.求单链表的长度

int LengthList(LinkList L){

Lnode *p;

int i = 0;

p=L->next;

while(p){

i++;

p=p->next;

}

return i;

}

6.取第i位置,返回该元素

int GetElem(LinkList L,int i,ElemType &e){

Lnode *p;

p=L->next;

int j=1;

if(p&&j

p=p->next;

j++;

}

if(!p||j>i) return error;

e=p->data;

return e;

}

9.插入-在第i个节点前插入值为e的新节点

1.首先要找到a(i-1)的存储位置

2.生成一个数据域为e的新结点s

3.插入新结点:1.新结点的指针域指向ai

2.结点a(i-1)的指针域指向新结点

s->next=p->next

p->next=s

Status InsertList(LinkList &L,int i,ElemType e){

Lnode *p;

p=L,j=0;

while(p||j

p=p->next;

++j;

}

if(!p||j>i-1) return error;

s=new Lnode;s->data=e;

s->next=p->next;

p->next=s;

return ok;

}

10.删除-删除第i个节点

Status deleteList(LinkList &L,int i){

Lnode *p;

p=L,j=0;

while(p||j

p=p->next;

++j;

}

if(!p||j>i-1) return error;

q=p->next;

p->next=q>next;

delete q;

return ok;

}

11.单链表:头插法

1.从一个空表开始

2.生成新结点,将读入数据存放到新结点

3.新结点依次插入头部

void CreatList(LinkList &L,int n){

L=new Lnode;

L->next = null;

for(i=n;i>0;i--){

p=new Lnode;

scanf(&p->data);

p->next=L->next;

L->next=p;

}

}

12.单链表:尾插法

void CreatList(LinkList &L,int n){

L=new Lnode;

L->next = null;

int i;

for(i=0;i

p=new Lnode;

scanf(&p->data);

p->next=null;

r->next=p;

r=p;

}

}

三.如何学好线性表的链式表示和实现?(How)

1.多总结、多思考、多输出

多找案例,多练,多敲

2.用心

搞清楚,链表的定义,各种操作,扎实基础。

用心

用心、用心

用心、用心、用心

知其然、知其所以然!!!

多学习,多思考,多总结,多输出,多交流 (five kills)~~~

相关内容

热门资讯

【实验报告】实验一 图像的... 实验目的熟悉Matlab图像运算的基础——矩阵运算;熟悉图像矩阵的显示方法࿰...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
大模型落地比趋势更重要,NLP... 全球很多人都开始相信,以ChatGPT为代表的大模型,将带来一场NLP领...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
kuernetes 资源对象分... 文章目录1. pod 状态1.1 容器启动错误类型1.2 ImagePullBackOff 错误1....
STM32实战项目-数码管 程序实现功能: 1、上电后,数码管间隔50ms计数; 2、...
TM1638和TM1639差异... TM1638和TM1639差异说明 ✨本文不涉及具体的单片机代码驱动内容,值针对芯...
Qt+MySql开发笔记:Qt... 若该文为原创文章,转载请注明原文出处 本文章博客地址:https://h...
Java内存模型中的happe... 第29讲 | Java内存模型中的happen-before是什么? Java 语言...
《扬帆优配》算力概念股大爆发,... 3月22日,9股封单金额超亿元,工业富联、鸿博股份、鹏鼎控股分别为3.0...
CF1763D Valid B... CF1763D Valid Bitonic Permutations 题目大意 拱形排列࿰...
SQL语法 DDL、DML、D... 文章目录1 SQL通用语法2 SQL分类3 DDL 数据定义语言3.1 数据库操作3.2 表操作3....
文心一言 VS ChatGPT... 3月16号,百度正式发布了『文心一言』,这是国内公司第一次发布类Chat...
CentOS8提高篇5:磁盘分...        首先需要在虚拟机中模拟添加一块新的硬盘设备,然后进行分区、格式化、挂载等...
Linux防火墙——SNAT、... 目录 NAT 一、SNAT策略及作用 1、概述 SNAT应用环境 SNAT原理 SNAT转换前提条...
部署+使用集群的算力跑CPU密... 我先在开头做一个总结,表达我最终要做的事情和最终环境是如何的,然后我会一...
Uploadifive 批量文... Uploadifive 批量文件上传_uploadifive 多个上传按钮_asing1elife的...
C++入门语法基础 文章目录:1. 什么是C++2. 命名空间2.1 域的概念2.2 命名...
2023年全国DAMA-CDG... DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义...
php实现助记词转TRX,ET... TRX助记词转地址网上都是Java,js或其他语言开发的示例,一个简单的...
【分割数据集操作集锦】毕设记录 1. 按要求将CSV文件转成json文件 有时候一些网络模型的源码会有data.json这样的文件里...
Postman接口测试之断言 如果你看文字部分还是不太理解的话,可以看看这个视频,详细介绍postma...
前端学习第三阶段-第4章 jQ... 4-1 jQuery介绍及常用API导读 01-jQuery入门导读 02-JavaScri...
4、linux初级——Linu... 目录 一、用CRT连接开发板 1、安装CRT调试工具 2、连接开发板 3、开机后ctrl+c...
Urban Radiance ... Urban Radiance Fields:城市辐射场 摘要:这项工作的目标是根据扫描...
天干地支(Java) 题目描述 古代中国使用天干地支来记录当前的年份。 天干一共有十个,分别为:...
SpringBoot雪花ID长... Long类型精度丢失 最近项目中使用雪花ID作为主键,雪花ID是19位Long类型数...
对JSP文件的理解 JSP是java程序。(JSP本质还是一个Servlet) JSP是&#...
【03173】2021年4月高... 一、单向填空题1、大量应用软件开发工具,开始于A、20世纪70年代B、20世纪 80年...
LeetCode5.最长回文子... 目录题目链接题目分析解题思路暴力中心向两边拓展搜索 题目链接 链接 题目分析 简单来说࿰...