数据结构——考研笔记(三)线性表之单链表

news2024/9/23 0:30:11

文章目录

      • 2.3 单链表
        • 2.3.1 知识总览
        • 2.3.2 什么是单链表
        • 2.3.3 不带头结点的单链表
        • 2.3.4 带头结点的单链表
        • 2.3.5 不带头结点 VS 带头结点
        • 2.3.6 知识回顾与重要考点
        • 2.3.7 单链表的插入和删除
          • 2.3.7.1 按位序插入(带头结点)
          • 2.3.7.2 按位序插入(不带头结点)
          • 2.3.7.3 指定结点的后插操作
          • 2.3.7.4 指定结点的前插操作
          • 2.3.7.5 按位序删除(带头结点)
          • 2.3.7.6 知识回顾与重要考点
        • 2.3.8 单链表的查找
          • 2.3.8.1 按位查找
          • 2.3.8.2 按值查找
          • 2.3.8.3 知识回顾与重要考点
        • 2.3.9 单链表的建立
          • 2.3.9.1 尾插法
          • 2.3.9.2 头插法


2.3 单链表

2.3.1 知识总览

image-20240715163504480

2.3.2 什么是单链表

image-20240715163622432

  • 顺序表

    • 优点:可随机存取,存储密度高
    • 缺点:要求大片连续空间,改变容量不方便
  • 单链表

    • 优点:不要求大片连续空间,改变容量方便
    • 缺点:不可随机存取,要消耗一定空间存放指针
  • 用代码实现单链表

image-20240715164545122

typedef struct LNode{			//定义单链表结点类型
    ElemType data;		//每个节点存放一个数据元素
    struct LNode* next;  //指针指向下一个节点
}LNode,*LinkList;
2.3.3 不带头结点的单链表
#include <stdlib.h>

typedef struct LNode {	//定义单链表结点类型
	int data;			//每个节点存放一个数据元素
	struct LNode* next; //指针指向下一个节点
}LNode,*LinkList;

//初始化一个空的单链表
bool InitList(LinkList& L) {
	L = NULL;	//空表,暂时还没有任何结点
	return true;
}

//判断单链表是否为空
bool Empty(LinkList L) {
	if (L == NULL)
		return true;
	else
		return false;
}

void test() {
	LinkList L;	//声明一个指向单链表的指针
	//初始化一个空表
	InitList(L);
	//……后续代码……
}
2.3.4 带头结点的单链表

image-20240715171402035

#include <stdlib.h>

typedef struct LNode {	//定义单链表结点类型
	int data;			//每个节点存放一个数据元素
	struct LNode* next; //指针指向下一个节点
}LNode, * LinkList;

//初始化一个空的单链表
bool InitList(LinkList& L) {
	L = (LNode*)malloc(sizeof(LNode));	//分配一个头节点
	if (L == NULL)			//内存不足,分配失败
		return false;
	L->next = NULL;			//头结点之后暂时还没有节点
	return true;
}

//判断单链表是否为空
bool Empty(LinkList L) {
	if (L->next == NULL)
		return true;
	else
		return false;
}

void test() {
	LinkList L;	//声明一个指向单链表的指针
	//初始化一个空表
	InitList(L);
	//……后续代码……
}
2.3.5 不带头结点 VS 带头结点

image-20240715171704621

  • 不带头结点:写代码更麻烦对第一个数据结点和后续数据结点的处理需要用不同的代码逻辑对空表和非空表的处理需要用到不同的代码逻辑
  • 带头结点:写代码更方便。
2.3.6 知识回顾与重要考点

image-20240715171817961

2.3.7 单链表的插入和删除

image-20240715172017835

2.3.7.1 按位序插入(带头结点)
  • ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。

image-20240715172337653

  • 代码展示

image-20240715174709999

#include <stdlib.h>

typedef struct LNode {	//定义单链表结点类型
	int data;			//每个节点存放一个数据元素
	struct LNode* next; //指针指向下一个节点
}LNode, * LinkList;

//初始化一个空的单链表
bool InitList(LinkList& L) {
	L = (LNode*)malloc(sizeof(LNode));	//分配一个头节点
	if (L == NULL)			//内存不足,分配失败
		return false;
	L->next = NULL;			//头结点之后暂时还没有节点
	return true;
}

//判断单链表是否为空
bool Empty(LinkList L) {
	if (L == NULL)
		return true;
	else
		return false;
}

//在第i个位置插入元素e(带头结点)
bool ListInsert(LinkList& L, int i, int e) {
	if (i < 1)
		return false;
	LNode* p;	//指针p指向当前扫描到的结点
	int j = 0;	//当前p指向的是第几个结点
	p = L;		//L指向头结点,头结点是第0个结点(不存数据)
	while (p != NULL && j < i - 1) {	//循环找到第i-1个结点
		p = p->next;
		j++;
	}
	if (p == NULL)	//i值不合法
		return false;
	LNode* s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;	//将结点s连到p之后
	return true;	//插入成功
}

void main() {
	LinkList L;	//声明一个指向单链表的指针
	//初始化一个空表
	InitList(L);
	//……后续代码……
}
2.3.7.2 按位序插入(不带头结点)

image-20240715175632081

  • 代码展示
#include <stdlib.h>

typedef struct LNode {	//定义单链表结点类型
	int data;			//每个节点存放一个数据元素
	struct LNode* next; //指针指向下一个节点
}LNode, * LinkList;

//初始化一个空的单链表
bool InitList(LinkList& L) {
	L = (LNode*)malloc(sizeof(LNode));	//分配一个头节点
	if (L == NULL)			//内存不足,分配失败
		return false;
	L->next = NULL;			//头结点之后暂时还没有节点
	return true;
}

//判断单链表是否为空
bool Empty(LinkList L) {
	if (L == NULL)
		return true;
	else
		return false;
}

//在第i个位置插入元素e(带头结点)
bool ListInsert(LinkList& L, int i, int e) {
	if (i < 1)
		return false;
	if (i = 1) {	//插入第1个结点的操作与其它结点的操作不同
		LNode* s = (LNode*)malloc(sizeof(LNode));
		s->data = e;
		s->next = L;
		L = s;		//头指针指向新节点
		return true;
	}
	LNode* p;	//指针p指向当前扫描到的结点
	int j = 1;	//当前p指向的是第几个结点
	p = L;		//L指向头结点,头结点是第0个结点(不存数据)
	while (p != NULL && j < i - 1) {	//循环找到第i-1个结点
		p = p->next;
		j++;
	}
	if (p == NULL)	//i值不合法
		return false;
	LNode* s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;	//将结点s连到p之后
	return true;	//插入成功
}

void main() {
	LinkList L;	//声明一个指向单链表的指针
	//初始化一个空表
	InitList(L);
	//……后续代码……
}
2.3.7.3 指定结点的后插操作

image-20240715180832621

//后插操作:在p结点之后插入元素e
bool InsertNextNode(LNode* p, int e) {
	if (p == NULL)
		return false;
	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL)	//内存分配失败
		return false;
	s->data = e;	//用结点s保存数据元素e
	s->next = p->next;
	p->next = s;	//将结点s连到p之后
	return true;
}
2.3.7.4 指定结点的前插操作

image-20240715181828300

  • 代码展示
//前插操作:在p结点之前插入元素e
bool InsertPriorNode(LNode* p, int e) {
	if (p == NULL)		//内存分配失败
		return false;
	LNode* s = (LNode*)malloc(sizeof(LNode));
	s->next = p->next;
	p->next = s;		//新结点s连到p之后
	s->data = p->data;	//将p中元素复制到s中
	p->data = e;		//p中元素覆盖为e
	return true;
}

2.3.7.5 按位序删除(带头结点)
  • ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。

image-20240715183805791

  • 代码展示
//删除表中第i个元素
bool ListDelete(LinkList& L, int i, int& e) {
	if (i < 1)
		return false;
	LNode* p;		//指针p指向当前扫描到的结点
	int j = 0;		//当前p指向的是第几个结点
	p = L;			//L指向头结点,头结点是第0个结点(不存数据)
	while (p != NULL && j < i - 1) {	//循环找到第i-1个结点
		p = p->next;
		j++;
	}
	if (p == NULL)	//i值不合法
		return false;
	if (p->next == NULL)	//第i-1个结点之后无其他结点
		return false;
	LNode* q = p->next;		//令q指向被删除结点
	e = q->data;			//用e返回元素的值
	p->next = q->next;		//将*q结点从链中“断开”
	free(q);				//释放结点的存储空间
	return true;			//删除成功
}
2.3.7.6 知识回顾与重要考点

image-20240715190156270

2.3.8 单链表的查找

image-20240715190606364

  • GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
  • LocalteElem(L,e):按值查找。在表L中查找具有给定关键字值的元素。
2.3.8.1 按位查找
  • 代码展示
//按位查找,返回第i个元素(带头结点)
LNode* GetElem(LinkList L, int i) {
	if (i < 0)
		return false;
	LNode* p;		//指针p指向当前扫描到的结点
	int j = 0;		//当前p指向的是第几个结点
	p = L;			//L指向头节点,头结点是第0个结点(不存数据)
	while (p != NULL && j < i) {	//循环找到第i个结点
		p = p->next;
		j++;
	}
	return p;
}
2.3.8.2 按值查找
  • 代码展示
//按值查找,找到数据域==e的结点
LNode* LocateElem(LinkList L, int e) {
	LNode* p = L->next;
	//从第1个结点开始查找数据域为e的结点
	while (p != NULL && p->data != e)
		p = p->next;
	return p;	//找到后返回该结点指针,否则返回NULL
}
2.3.8.3 知识回顾与重要考点

image-20240715192241414

2.3.9 单链表的建立

image-20240715192343150

如果给你很多个数据元素(ElemType),要把它们存到一个单链表里边,怎么办呢?

step1:初始化一个单链表

step2:每次取一个数据元素,插入到表尾/表头

2.3.9.1 尾插法
  • 代码展示
//尾插法
LinkList List_TailInsert(LinkList& L) {	//正向建立单链表
	int x;								
	L = (LinkList)malloc(sizeof(LNode));//建立头结点
	LNode* s, * r = L;					//r为表尾指针
	scanf("%d", &x);					//输入结点的值
	while (x != 9999) {					//输入9999表示结束
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;							//r指向新的表尾结点
		scanf("%d", &x);
	}
	r->next = NULL;						//尾结点指针置空
	return L;
}
2.3.9.2 头插法
  • 代码展示
//头插法
LinkList List_HeadInsert(LinkList& L) {
	LNode* s;
	int x;
	L = (LNode*)malloc(sizeof(LNode));	//建立头结点
	L->next = NULL;						//初始化空链表
	scanf_s("%d", &x);					//输入结点的值
	while (x != 9999) {					//输入9999表示结束
		s = (LNode*)malloc(sizeof(LNode));//创建新结点
		s->data = x;
		s->next = L->next;
		L->next = s;					//将新结点插入表中,L为头指针
		scanf_s("%d", &x);
	}
	return L;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1928277.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI写作不懂提示词 大象Prompt 保姆级系列教程三

一、提示词的核心价值究竟是啥&#xff1f; 最近跟不少业内朋友探讨这事儿&#xff0c;我觉得&#xff1a;提示词的核心价值在于对方法论的封装以及由此带来的知识传播速度加快。 通俗讲&#xff0c;假如你熟悉的行业里有个厉害的“老师傅”&#xff0c;他在核心业务上有好多心…

通用图形处理器设计GPGPU基础与架构(三)

一、前言 前两篇已经介绍了 GPGPU 的背景 和 GPGPU 的编程模型相关的内容&#xff0c;本文将在 SIMT 计算模型的基础上&#xff0c;介绍 GPGPU 控制核心架构和微体系结构的设计。 二、CPU-GPGPU 异构计算系统 一个由 CPU 和 GPGPU 构成的异构计算平台如下图所示&#xff0c;GP…

【常见开源库的二次开发】基于openssl的加密与解密——Base的编解码(二进制转ascll)(二)

目录&#xff1a; 目录&#xff1a; 一、 Base64概述和应用场景 1.1 概述 1.2 应用场景 二、Base16 2.1 Base16编码 2.2 Base16编解码 三、Base64 四、OpenSSL BIO接☐ 4.1 Filter BIOs&#xff1a; 4.2 Source/Sink BIOs&#xff1a; 4.3 应用场景&#xff1a; 4.4 具体使用&…

HCIE是什么等级的证书?

HCIE&#xff08;华为认证互联网专家&#xff0c;Huawei Certified Internetwork Expert&#xff09;是华为认证体系中的最高等级证书。它要求考生具备在复杂网络环境中规划、设计、部署、运维和优化网络的能力。HCIE认证是华为认证体系中最具挑战性和含金量的认证之一&#xf…

EPLAN 去掉PDF中的红色跳转标识

EPLAN PDF图纸导出后体验跳转标识会有红色标识&#xff0c;如何去掉呢&#xff1f;下面介绍一下方法&#xff1a; 此为现象&#xff1a; EPLAN 2.9的帮助文档里提示&#xff1a; 在导出的 PDF 文档中&#xff0c;跳转后的跳转目标现在通过红色的闪烁框进行标识。可能的跳转目…

探索Node.js中的node-xlsx:将Excel文件解析为JSON

在Node.js开发中&#xff0c;处理Excel文件是一个常见需求&#xff0c;特别是在需要导入大量数据或生成报表的场景中。node-xlsx 是一个强大的库&#xff0c;它提供了Excel文件的解析和生成功能。本文将深入探讨 node-xlsx 的使用&#xff0c;并通过一个案例演示如何将Excel文件…

蒙特卡洛树搜索

目录 1. 选择&#xff08;Selection&#xff09;2. 扩展&#xff08;Expansion&#xff09;3. 模拟&#xff08;Simulation&#xff09;4. 反向传播&#xff08;Backpropagation&#xff09;为什么蒙特卡洛树搜索很厉害&#xff1f;应用实例 蒙特卡洛树搜索介绍 蒙特卡洛树搜索…

【从0到1进阶Redis】哨兵模式

笔记内容来自B站博主《遇见狂神说》&#xff1a;Redis视频链接 小伙伴们可以看一下上一篇我的Redis笔记 —— 【从0到1进阶Redis】主从复制 这样可以更好的理解原理。 一、概述 主从切换技术的方法是&#xff1a;当主服务器宕机后&#xff0c;需要手动把一台从服务器切换为主服…

Parallels Desktop 19 for Mac(PD19虚拟机)详细图文安装教程分享

Parallels Desktop 19是一款功能丰富、性能强大且易于使用的虚拟机软件&#xff0c;它可以让您在Mac上同时运行多个操作系统&#xff0c;为您提供更大的灵活性和兼容性。 Parallels Desktop 19 for Mac(PD19虚拟机)下载安装包 Parallels Desktop 19 for Mac(PD19虚拟机)详细图…

在VS2017下FFmpeg+SDL编写最简单的视频播放器

1.下载ShiftMediaProject/FFmpeg 2.下载SDL2 3.新建VC控制台应用 3.配置include和lib 4.把FFmpeg和SDL的dll 复制到工程Debug目录下&#xff0c;并设置调试命令 5.复制一下mp4视频到工程Debug目录下&#xff08;复制一份到*.vcxproj同一目录&#xff0c;用于调试&#xff09; 6…

虚拟机的状态更新

文章目录 虚拟机的更新一、检查虚拟机的配置1.已连接状态2. 保证镜像源挂载 二、进行更新三、其余事项 虚拟机的更新 虚拟机的更新是确保系统软件包和库的更新&#xff0c;以获得最新的修复和改进&#xff1b;如果长期没有打开单机或者集群&#xff0c;可以考虑先进行一次更新…

CentOS 停服后,服务器 OS 路在何方?

2024 年 6 月 30 日&#xff0c;CentOS Linux 7 终止其生命周期&#xff08;EOL&#xff09;&#xff0c;至此 CentOS 全系列版本也已停止维护&#xff0c;属于 CentOS 的时代彻底终结。CentOS 停止维护后&#xff0c;用户将无法获得包括问题修复和功能更新在内的任何软件维护和…

深度学习与神经网络介绍

目录 一&#xff1a;深度学习的概念 二&#xff1a;机器学习和深度学习的区别 1.特征提取&#xff1a; 三&#xff1a;深度学习的应用场景 1.图像识别 2.自然语言处理技术 3.语音技术 四&#xff1a;神经网络的介绍 1.人工神经网络的概念 2.神经元的概念 3.单层神经网…

【论文阅读】《Visual Prompt Tuning》

Abstract. 目前调整预训练模型的工作方式包括更新所有骨干参数&#xff0c;即全面微调。本文介绍了视觉提示调整&#xff08;VPT&#xff09;&#xff0c;作为大规模视觉变换器模型全面微调的高效替代方案。VPT 从高效调整大型语言模型的最新进展中汲取灵感&#xff0c;只在输…

uniapp 实现上传文件的功能

上传单个文件 <script setup>const handleUploadClick () > {console.log("上传文件")uni.chooseImage({success: (chooseImageRes) > {const tempFilePaths chooseImageRes.tempFilePaths;console.log("用户选择的图片&#xff1a;", temp…

华为HCIP Datacom H12-821 卷40

1.单选题 下面是台路由器BGP错误输出信息&#xff0c;关于这段信息描述错误的是 <HUAWEI>display bgp error Error Type :Peer Error Date/Time :2010-03-22 12:40:39 Peer Address :10.1.1.5 Error Info : Incorrect remote AS A、可能是由于邻居…

二叉树 —— OJ题目详解

1.二叉树的前序遍历 二叉树的前序遍历比较简单&#xff0c;但是在力扣上写这个接口需要注意几个点&#xff1a; int* preorderTraversal(struct TreeNode* root, int* returnSize) {} preorderTraversal 的返回值是动态开辟的数组&#xff0c;里面存放的是前序遍历的顺序int*…

Python 获取今天(当天)、昨天(前一天)、前天(昨天的前一天)的开始时间、结束时间

描述&#xff1a;我这里是封装成DatetimeHelper工具类来调用 1.今天(当天)开始时间、结束时间 from datetime import datetime, timedeltaclass DatetimeHelper:# 获取今天(当天)的开始时间、结束时间(datetime类型)staticmethoddef getTodayStartEnd():# 获取当前的日期now …

JVM监控及诊断工具-命令行篇--jinfo命令介绍

JVM监控及诊断工具-命令行篇02-jinfo&#xff1a;实时查看和修改JVM配置参数 一 基本情况二 基本语法2.1查看jinfo -sysprops PIDjinfo -flags PIDjinfo -flag 具体参数 PID 2.2修改 三 拓展java -XX:PrintFlagsInitialjava -XX:PrintFlagsFinaljava -XX:PrintCommandLineFlags…

IP风险画像 金融行业的安全盾牌

在当今数字化时代&#xff0c;金融行业面临着前所未有的安全挑战。随着在线交易和数字银行业务的迅猛发展&#xff0c;欺诈和网络攻击的威胁也在不断增加。金融机构需要高效、可靠的安全解决方案来保护客户的资产和个人信息&#xff0c;防止各种形式的欺诈行为。 IP风险画像是…