[一篇读懂]C语言十讲:单链表的新建、查找

news2025/3/1 4:00:12

[一篇读懂]C语言十讲:单链表的新建、查找

  • 1. 与408关联解析及本节内容介绍
    • 1 与408关联解析
    • 2 本节内容介绍
  • 2. 头插法新建链表实战
  • 3. 尾插法新建链表实战
  • 4. 按位置查找及按值查找实战
  • 5. 往第i个位置插入元素实战
  • 6. 链表的调试方法
  • 总结
    • 2
    • 3
    • 4
    • 5
    • 6


1. 与408关联解析及本节内容介绍

1 与408关联解析

【2019年单链表】
41.(13分)设线性表 L = ( a 1 , a 2 , a 3 , … , a n − 2 , a n − 1 , a n ) L=(a_1,a_2 ,a_3,…,a_{n-2},a_{n-1},a_n) L=(a1,a2,a3,,an2,an1,an)采用带头结点的单链表保存,链表中的结点定义如下:

typedef struct node {
	int data;
	struct node* next;
}NODE;

请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表 L = ( a 1 , a n , a 3 , a n − 1 , a 3 , a n − 2 , … ) L=(a_1,a_n ,a_3,a_{n-1},a_3,a_{n-2},…) L=(a1,an,a3,an1,a3,an2,)。要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
(3)说明你所设计的算法的时间复杂度。

2 本节内容介绍

本节分为五小节讲解。
第一小节是针对头插法新建链表进行实战
第二小节是针对尾插法新建链表进行实战
第三小节是链表按位置查找及按值查找实战
第四小节是往第i个位置插入元素实战
第五小节是链表的调试方法解析


2. 头插法新建链表实战

  • 一切数据结构 - 增删查改

上一讲介绍了链表的新增、删除、查找的原理。

  • 头插法新建链表流程图:
    1

画流程图很关键。

使用头插法来新建链表:

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType; //写分号

typedef struct LNode
{
	ElemType data; //数据域
	struct LNode* next;
}LNode,*LinkList;

//输入3,4,5,6,7,9999
void list_head_insert(LNode*& L)//LNode*是结构体指针 等价于 LinkList(常用)
{
	//申请头结点空间,头指针指向头结点
	L = (LinkList)malloc(sizeof(LNode));//不能写LinkList和LNode* - 结构体指针 - 大小8个字节
	L->next = NULL;//头结点的next为NULL - 第一次读取时s->next = L->next =NULL
	//第一个结点
	ElemType x;//第一个结点的数据
	scanf("%d", &x);
	LNode *s;//指针s指向第一个结点
	//s = (LinkList)malloc(sizeof(LNode));
	//s->data = x;//x存放到数据域中
	//s->next = NULL;//第一个结点最后会成为最后一个结点 - next指针应该为NULL
	//L->next = s;//头结点的next,就指向了第一个结点

	while (x != 9999)//输入9999代表输入结束 - 不想把9999存入链表
	{
		//scanf("%d", &x);
		s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		//头插法,把插入的元素插到第一个位置
		s->next = L->next;//s的next指向原本链表的第一个结点
		L->next = s;//头结点的next指向新结点
		scanf("%d", &x);//读取放在最后,读到结束的9999时就不会存入链表
	}

}

void print_list(LinkList L)
{
	L = L->next;
	while (L != NULL)
	{
		printf("%3d", L->data);
		L = L->next;
	}
	printf("\n");
}

//头插法新建链表
int main()
{
	LinkList L; //L是链表头指针,是结构体指针类型 - 大小8个字节

	list_head_insert(L); //输入数据可以为3 4 5 6 7 9999,头插法新建链表
	print_list(L); //链表打印
	return 0;
}

3. 尾插法新建链表实战

  • 尾插法新建链表流程图:
    1
    使用尾插法来新建链表:
#include <stdio.h>
#include <stdlib.h>

typedef int ElemType; //写分号

typedef struct LNode
{
	ElemType data; //数据域
	struct LNode* next;
}LNode, * LinkList;

void list_tail_insert(LNode*& L)
{
	L = (LinkList)malloc(sizeof(LNode));//申请头结点空间,头指针指向头结点
	L->next = NULL;//头结点的next为NULL
	ElemType x;
	scanf("%d", &x);
	LNode* s, * r = L;//s用来指向申请的新节点,r始终指向列表尾部
	while (x != 9999)
	{
		s = (LinkList)malloc(sizeof(LNode));//为新节点申请空间
		s->data = x;
		r->next = s;//新节点给尾节点的next指针
		r = s;//r要指向新的尾部
		scanf("%d", &x);
	}
	r->next = NULL;//让尾节点的next为NULL
}

void print_list(LinkList L)
{
	L = L->next;
	while (L != NULL)
	{
		printf("%3d", L->data);
		L = L->next;
	}
	printf("\n");
}

//尾插法新建链表
int main()
{
	LinkList L; //L是链表头指针,是结构体指针类型 - 大小8个字节
	list_tail_insert(L);
	print_list(L); //链表打印
	return 0;
}

4. 按位置查找及按值查找实战

  • 按位置查找流程图:1
  • 查找位置时需要判断位置是否合法。
#include <stdio.h>
#include <stdlib.h>

typedef int ElemType; //写分号

typedef struct LNode
{
	ElemType data; //数据域
	struct LNode* next;
}LNode, * LinkList;


void list_tail_insert(LNode*& L)
{
	L = (LinkList)malloc(sizeof(LNode));//申请头结点空间,头指针指向头结点
	L->next = NULL;//头结点的next为NULL
	ElemType x;
	scanf("%d", &x);
	LNode* s, * r = L;//s用来指向申请的新节点,r始终指向列表尾部
	while (x != 9999)
	{
		s = (LinkList)malloc(sizeof(LNode));//为新节点申请空间
		s->data = x;
		r->next = s;//新节点给尾节点的next指针
		r = s;//r要指向新的尾部
		scanf("%d", &x);
	}
	r->next = NULL;//让尾节点的next为NULL
}

void print_list(LinkList L)
{
	L = L->next;
	while (L != NULL)
	{
		printf("%3d", L->data);
		L = L->next;
	}
	printf("\n");
}

//按位置查找
LinkList GetElem(LinkList L, int SearchPos)
{
	int j = 0;
	while (L && j < SearchPos)//L!=NULL,地址不为NULL
	{
		L = L->next;
		j++;
	}
	return L;
}

//按值查找
LinkList LocateElem(LinkList L, ElemType SearchVal)
{
	while (L)
	{
		if (L->data == SearchVal)//如果找到对应的值,返回那个节点的地址
		{
			return L;
		}
		L = L->next;
	}
	return NULL;
}

//尾插法新建链表
int main()
{
	LinkList L; //L是链表头指针,是结构体指针类型 - 大小8个字节

	list_tail_insert(L);
	print_list(L); //链表打印

	LinkList search;//用来存储拿到的某一个节点
	//按位置查找
	search = GetElem(L, 2);
	if (search != NULL)
	{
		printf("Secceeded in searching by serial number\n");
		printf("%d\n", search->data);
	}

	//按值查找
	search = LocateElem(L, 6);
	if (search != NULL)
	{
		printf("Secceeded in searching by serial number\n");
		printf("%d\n", search->data);

	}
	return 0;
}

5. 往第i个位置插入元素实战

  • 往第i个位置插入元素流程图:
    1
  • 如果要从函数调用位置,跳转到函数定义位置,ctrl+鼠标左键点击
#include <stdio.h>
#include <stdlib.h>

typedef int ElemType; //写分号

typedef struct LNode
{
	ElemType data; //数据域
	struct LNode* next;
}LNode, * LinkList;


void list_tail_insert(LNode*& L)
{
	L = (LinkList)malloc(sizeof(LNode));//申请头结点空间,头指针指向头结点
	L->next = NULL;//头结点的next为NULL
	ElemType x;
	scanf("%d", &x);
	LNode* s, * r = L;//s用来指向申请的新节点,r始终指向列表尾部
	while (x != 9999)
	{
		s = (LinkList)malloc(sizeof(LNode));//为新节点申请空间
		s->data = x;
		r->next = s;//新节点给尾节点的next指针
		r = s;//r要指向新的尾部
		scanf("%d", &x);
	}
	r->next = NULL;//让尾节点的next为NULL
}

void print_list(LinkList L)
{
	L = L->next;
	while (L != NULL)
	{
		printf("%3d", L->data);
		L = L->next;
	}
	printf("\n");
}

//按位置查找
LinkList GetElem(LinkList L, int SearchPos)
{
	int j = 0;
	if (SearchPos < 0)
	{
		return NULL;
	}
	while (L && j < SearchPos)//L!=NULL,地址不为NULL
	{
		L = L->next;
		j++;
	}
	return L;
}

//按值查找
LinkList LocateElem(LinkList L, ElemType SearchVal)
{
	while (L)
	{
		if (L->data == SearchVal)//如果找到对应的值,返回那个节点的地址
		{
			return L;
		}
		L = L->next;
	}
	return NULL;
}

//i代表插入到第几个位置
bool ListFrontInsert(LinkList L, int i, ElemType InsertVal)
{
	LinkList p = GetElem(L, i - 1);
	if (NULL == p)
	{
		return false;
	}
	LinkList q;
	q = (LinkList)malloc(sizeof(LNode));//为新节点申请空间
	q->data = InsertVal;
	q->next = p->next;
	p->next = q;
	return true;
}

//尾插法新建链表
int main()
{
	LinkList L; //L是链表头指针,是结构体指针类型 - 大小8个字节

	list_tail_insert(L);
	print_list(L); //链表打印

	LinkList search;//用来存储拿到的某一个节点
	bool ret;
	ret = ListFrontInsert(L, 2, 99);//新节点插入第i个位置
	print_list(L); 
	return 0;
}

6. 链表的调试方法

  • 链表中每一个结点在内存中是不连续的,通过单步调试,在变量窗口,依次点开头指针L,观察每一个结点是否符合自己的预期。
    1

总结

2

  • 头插法新建链表流程图:
    1

3

  • 尾插法新建链表流程图:
    1

4

  • 按位置查找流程图:1

5

  • 往第i个位置插入元素流程图:
    1

6

  • 链表中每一个结点在内存中是不连续的,通过单步调试,在变量窗口,依次点开头指针L,观察每一个结点是否符合自己的预期。

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

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

相关文章

面对无法投入模型训练的object类型数据在头疼,快来使用我的丝滑小连招

面对无法投入模型训练的object类型数据在头疼&#xff0c;快来使用我的丝滑小连招 前言 丝滑小连招 tip1- get_dummies完美one-hot&#xff08;str->int&#xff09; tip2 - rename_dims解决重名问题&#xff01; tip3 - insert且drop&#xff01;​​​​​​​ 前言 我…

小爱同学控制美的美居中的家电热水器,空调等

背景 家里大多数家电都是支持接入米家App的&#xff0c;美的家电不能接入小米&#xff0c;电脑安装Home Assistant成功实现小爱语音控制美的燃气热水器。 实现步骤&#xff1a; 1. 安装docker 我的电脑是windows的&#xff0c;那就直接安装docker desktop https://desktop.…

【Linux】基础指令(三) —— 收尾篇

文章目录前言zip 和 unzip 指令tar 指令bc 指令uname 指令history关机热键补充ctrl c↑ && ↓ctrl rctrl d指令拓展结语前言 今天为大家带来的是最后一部分基础指令讲解。主要内容为 7个指令讲解、热键补充、简单提一下指令的拓展 。内容相对之前较少&#xff0c;更…

服务器密码以及用户名怎么修改

服务器密码以及用户名怎么修改 我是艾西&#xff0c;今天给大家说下服务器密码如何修改 windows2003系统&#xff1a; 1、右键我的电脑&#xff0c;点击“管理”&#xff1a; 2、在“本地用户和组”中打开“用户”&#xff0c;在右侧找到 Administrator 账户进行修改。 200…

【linux】linux实操篇之任务调度

目录前言crond 任务调度概述基本语法快速入门案例案例一&#xff1a;每隔一分钟将ls -l /etc/ 追加到 /tmp/to.txt 文件案例二&#xff1a;每隔一分钟执行python文件结语前言 我们常用linux做一些定时任务&#xff0c;最常见的就是在服务器领域&#xff0c;我们常常做一些定时…

高分辨率格式理论

一个核心概念&#xff1a;人工粘性 考虑经典的双曲守恒律方程 ∂u∂t∂f∂x0{{\partial u} \over {\partial t}} {{\partial f} \over {\partial x}} 0∂t∂u​∂x∂f​0 可以写成守恒形式的数值格式 uin1uin−λ(f^i1/2n−f^i1/2n)u_i^{n 1} u_i^n - \lambda \left( {\ha…

基于ssm+mysql+jsp学生成绩管理系统(含实训报告)

基于ssmmysqljsp学生成绩管理系统(实训报告&#xff09;一、系统介绍二、功能展示1.学生信息查询2.学生信息添加3.学生信息修改4.学生信息删除四、获取源码一、系统介绍 系统主要功能&#xff1a;系统实现了学生信息查询、添加、修改、删除。 环境配置&#xff1a; Jdk1.8 M…

[附源码]java毕业设计智慧教学平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

储能辅助电力系统调峰的容量需求优化配置matlab/cplex

参考文献&#xff1a;储能辅助电力系统调峰的容量需求研究 摘要&#xff1a;建立了储能辅助电力系统调峰的容量需求优化配置模型&#xff0c;设置了含储能和不含储能两种仿真方案&#xff0c;将两个算例代入所提模型进行求解&#xff0c;得到最优的储能系统容量和功率配置&…

Flutter高仿微信-第52篇-群聊-清空聊天记录

Flutter高仿微信系列共59篇&#xff0c;从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。 详情请查看 效果图&#xff1a; 实现代码&#xff1a; //清空聊天记录对话框 void _cleanGroupChatDialog(){Lo…

【Python】数据类型 + 运算符 + 输入输出

文章目录一. 常量和表达式二. 变量和类型1. 什么是变量2. 变量的语法2.1 定义变量2.2 使用变量3. 变量的类型3.1 整数3.2 浮点数3.3 字符串3.4 布尔3.5 关于变量类型的几点补充三. 注释1. 什么是注释&#xff1f;2. 为什么要有注释&#xff1f;3. 如何写注释&#xff1f;3.1 注…

深度学习制作自己的数据集—为数据集打上标签保存为txt文件,并进行划分和加载数据集

目录 0 前言 1 为图片数据集打上标签并保存为txt文件 2 将txt文件中的图片标签数据集随机划分为训练集和测试集 3 加载txt文件中的图片标签数据集 0 前言 目前是被封控的第四天了&#xff0c;只能呆在宿舍不能出去&#xff0c;记得上次这样子还是一年前大四快毕业那时候了……

CyberController手机外挂番外篇:源代码的二次修改

文章目录前言调试过程中的疑问为什么一段时间不使用CyberController&#xff0c;翻译就无法触发了&#xff1f;为什么连接成功了&#xff0c;但却依然无法进行语音识别和翻译&#xff1f;多长时间TCP连接就会挂掉连接正常与断开连接有什么区别&#xff1f;不停进行翻译&#xf…

现代密码学导论-18-伪随机置换

目录 伪随机置换 PROPOSITION 3.26 伪随机置换和伪随机函数的关系 DEFINITION 3.27 强伪随机置换 伪随机置换 我们称F是含参数k的置换&#xff0c;当且仅当 且对于所有k&#xff0c; Fk是一对一的&#xff0c;即是满射的。 其中 lin 称为F的块长度 对于给定的 k、x和k、y&…

76.【图】

图( 一).图的基本结构(1).无序偶对.(2).有序偶对(3).有向图和无向图(4).权(5).网图(二).图的基本术语(1).邻接.依附(2).有向完全图,无向完全图(3).顶点的度,入度,出度(4).路径 路径长度 回路(5).简单路径 简单回路(6).子图(7).连通图 连通分量(8).强连通图 强连通分量(三).图的…

改进粒子滤波的无人机三维航迹预测方法(基于Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

骨传导耳机贴不紧咋办,推荐五款佩戴最稳固的骨传导蓝牙耳机

很多小伙伴都在反馈&#xff0c;骨传导耳机在佩戴时戴不稳&#xff0c;这关乎于耳机的材质有很大的关系&#xff0c;下面就给大家推荐几款佩戴十分牢固的骨传导耳机&#xff0c;不调人群使用哦~看看有没有自己喜欢的吧~ 1、南卡Runner Pro4骨传导蓝牙耳机 &#xffe5;1498 南…

图与图的深度优先遍历、广度优先遍历

文章目录&#x1f6a9;图的理解&#x1f341;无向图&#x1f341;有向图&#x1f341;完全图&#x1f341;常用性质&#x1f6a9;图的数据结构搭建&#x1f341;邻接矩阵&#x1f341;邻接表&#x1f341;邻接矩阵式存储的代码实现&#x1f341;邻接矩阵造图测试&#x1f341;邻…

从零开始打造一款基于SpringBoot+SpringCloud的后台权限管理系统

随着 Spring Boot 和 Spring Cloud 的诞生和流行&#xff0c;集智慧于大成的 Spring 技术体系成为行业开发的首选之一。市场代表需求&#xff0c;技术代表能力。显而易见&#xff0c;在当今开发领域中&#xff0c;谁能更好地掌握这些主流开发技术&#xff0c;谁就能在跟别人竞争…

SecXOps 技术体系

核心能力 为了加快安全分析能力更全面、更深入的自动化 &#xff0c;SecXOps 的目标在于创建一个集成的用于 Security 的 XOps 实践&#xff0c;提升安全分析的场景覆盖率和运营效率。SecXOps 技术并不 015 SecXOps 技术体系 是 Ops 技术在安全领域的简单加和&#xff0c;SecXO…