链表的应用

链表优点:链表各个节点个数可以灵活变动,学生多时可以增加节点,少时可以减少节点,链表不要求存储空间连续,空间利用率高

链表:链表中每个节点在内存中位置不一定连续,所以每一节点中一定有个字段存放下一个节点的地址,如此便可已形成链表结构

链表的每个节点在内存中位置不一定连续
每一节点中一定有一个字段存放下一个节点的地址

链表的分类:单向链表、单向循环链表、双向链表、双向循环链表

单像链表的标准结构:
struct Node
{
类型 data;//存放数据比如学生的学号
Node * next;//存放下一个节点的地址(必须有)
};

#include <stdio.h>
#include <stdlib.h>
#include <string.h>//定义单向链表的节点
struct Node
{//数据成员,可以是原始类型,也可以是struct,enum,unionchar name[32];//一定不能缺的成员struct Node * next;//指向下一个节点的指针
};int main()
{//产生3个节点struct Node stu1;struct Node stu2;struct Node stu3;//给节点的数据赋值strcpy(stu1.name,"学生A");strcpy(stu2.name,"学生B");strcpy(stu3.name,"学生C");//上面三个节点是散乱分布的,需要把他们穿成链表//stu1作为头节点,stu3作为尾节点stu1.next=&stu2;stu2.next=&stu3;stu3.next=NULL;//stu3是最后一个节点,所以next为NULL//打印链表,从链表头开始struct Node *pHead = &stu1;//头指针指向第一个节点while(pHead!=NULL){printf("%s  ",pHead->name);pHead = pHead->next;//获取下一个节点的内存地址}printf("\n");return 0;
}

在这里插入图片描述
向链表的尾部插入节点

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>//定义单向链表的节点
struct Node
{//数据成员,可以是原始类型,也可以是struct,enum,unionchar name[32];//节点的数据成员//一定不能缺的成员struct Node *next;//指向下一个节点的指针
};int main()
{//定义两个节点指针,一个指向头节点(方便遍历),一个指向尾节点(方便插入)struct Node *pHead = NULL;struct Node *pTail = NULL;//空链表的时候//让用户可以随时输入学生while(1){printf("请输入学生姓名,quit(退出) print(打印):\n");char name[32] = {0};scanf("%s",name);if(strcmp(name,"quit")==0)break;else if(strcmp(name,"print")==0){struct Node *pNode = pHead;//不要改变pHead的值,让他一直指向头部while(pNode!=NULL){printf("%s  ",pNode -> name);pNode = pNode->next;//指向下一个节点}printf("\n");}else{//struct Node stu;//可以定义节点,但是这样定义的话离开}内存就释放了,stu是局部变量//分配节点堆内存,除非free,否则一直有效struct Node *pNode = (struct Node*)malloc(sizeof(struct Node));strcpy(pNode->name,name);pNode->next = NULL;//因为这个节点即将作为尾部节点//把节点放在链表中//判断是不是第一个节点if(pHead==NULL){pHead = pNode;pTail = pNode;//第一个节点既是头,又是尾部}else{pTail -> next = pNode;//让一个尾巴的next = 新节点pTail = pNode;//让pTail始终指向最新的尾巴}}}return 0;
}

在这里插入图片描述
向链表头部插入节点

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>//定义单向链表的节点
struct Node
{//数据成员,可以是原始类型,也可以是struct,enum,unionchar name[32];//节点的数据成员//一定不能缺的成员struct Node *next;//指向下一个节点的指针
};int main()
{//定义两个节点指针,一个指向头节点(方便遍历),一个指向尾节点(方便插入)struct Node *pHead = NULL;struct Node *pTail = NULL;//空链表的时候//让用户可以随时输入学生while(1){printf("请输入学生姓名,quit(退出) print(打印):\n");char name[32] = {0};scanf("%s",name);if(strcmp(name,"quit")==0)break;else if(strcmp(name,"print")==0){struct Node *pNode = pHead;//不要改变pHead的值,让他一直指向头部while(pNode!=NULL){printf("%s  ",pNode -> name);pNode = pNode->next;//指向下一个节点}printf("\n");}else{//struct Node stu;//可以定义节点,但是这样定义的话离开}内存就释放了,stu是局部变量//分配节点堆内存,除非free,否则一直有效struct Node *pNode = (struct Node*)malloc(sizeof(struct Node));strcpy(pNode->name,name);pNode->next = pHead;//让新节点的下一个指向之前链表的头节点(pHead)//在这个时候,pHead依然指向上一次的头节点,而此刻头节点已经变成我们的新节点//所以需要更新pHead的值pHead=pNode;//只想最新的头结点}}return 0;
}

在这里插入图片描述
在链表中部插入节点

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>//定义单向链表的节点
struct Node
{char name[32];struct Node *next;
};void PrintList(struct Node *pHead)//指针的拷贝,不会影响实参
{while(pHead){printf("%s  ",pHead->name);pHead = pHead->next;}printf("\n");
}int main()
{//定义一条链表,两个节点A,Bstruct Node A;strcpy(A.name,"学生A");struct Node B;strcpy(B.name,"学生B");//形成一条链表A.next=&B;B.next=NULL;//在A,B之间插入新节点struct Node C;strcpy(C.name,"学生C");//插入//C.next=&B;//C->B//A.next=&C;//A->C//或C.next = (&A)->next;//或C.next = A.next;A.next = &C;//打印链表PrintList(&A);return 0;
}

删除单向链表尾部结点

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>struct Node
{char name[32];struct Node *next;
};//创建一个链表,拥有N个节点,尾插法
struct Node * CreateList(int N)
{struct Node *pHead = NULL;struct Node *pTail = NULL;for(size_t i=0; i<N; i++){struct Node *pNode = (struct Node *)malloc(sizeof(struct Node));sprintf(pNode -> name,"学生%d",i+1);pNode -> next = NULL;if(pHead == NULL)pHead = pNode;elsepTail -> next = pNode;pTail = pNode;}return pHead;//返回链表头结点的指针
}//打印一条链表
void PrintLinst(struct Node *pHead)
{while(pHead!=NULL){printf("%s  ",pHead -> name);pHead = pHead -> next;//pHead的改变不影响实参,因为是参数的拷贝}printf("\n");
}//删除链表的尾部节点
struct Node * DeleteTail(struct Node *pHead)
{//需要判断这个链表是否只有一个节点,不存在倒数第二个节点if(pHead -> next == NULL){printf("当前链表只有一个节点\n");free(pHead);//删完后,这条链表一个节点也没有了return NULL;}struct Node *pTemp = pHead;//需要获取尾部节点的前一个节点指针(因为我们要把前一个节点的next设置为NULL)while(pTemp -> next -> next != NULL){pTemp = pTemp -> next;//pTemp的改变不影响实参}printf("当前节点是:%s\n",pTemp -> name);//删除最后一个节点的内存free(pTemp -> next);//将倒数第二个的next置为NULL,让倒数第二个变成尾节点pTemp -> next = NULL;return pHead;
}int main()
{struct Node *pHead = CreateList(5);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);//接受新的pHeadpHead = DeleteTail(pHead);PrintLinst(pHead);return 0;
}

在这里插入图片描述

删除单向链表头部节点

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>struct Node
{char name[32];struct Node *next;
};//创建一个链表,拥有N个节点,尾插法
struct Node * CreateList(int N)
{struct Node *pHead = NULL;struct Node *pTail = NULL;for(size_t i=0; i<N; i++){struct Node *pNode = (struct Node *)malloc(sizeof(struct Node));sprintf(pNode -> name,"学生%d",i+1);pNode -> next = NULL;if(pHead == NULL)pHead = pNode;elsepTail -> next = pNode;pTail = pNode;}return pHead;//返回链表头结点的指针
}//打印一条链表
void PrintLinst(struct Node *pHead)
{while(pHead!=NULL){printf("%s  ",pHead -> name);pHead = pHead -> next;//pHead的改变不影响实参,因为是参数的拷贝}printf("\n");
}//删除链表的尾部节点
//错误版本
struct Node * _DeleteTail(struct Node *pHead)
{printf("释放内存前,打印第二个节点的地址%p\n",pHead -> next);free(pHead);//释放头节点的内存printf("释放内存后,打印第二个节点的地址%p\n",pHead -> next);//此刻,pHead指向的内存已经无效pHead = pHead -> next;//让头结点的指针指向第二个节点return pHead;
}//删除链表的尾部节点
//正确版本
struct Node * DeleteTail(struct Node *pHead)
{if(pHead == NULL)return NULL;struct Node *pTemp = pHead -> next;free(pHead);//释放头节点的内存//此刻,pHead指向的内存已经无效pHead = pTemp;//让头结点的指针指向第二个节点return pHead;
}int main()
{struct Node *pHead = CreateList(5);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);pHead = DeleteTail(pHead);PrintLinst(pHead);return 0;
}

在这里插入图片描述
删除单向链表中部节点

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
using namespace std;struct Node
{char name[32];struct Node *next;
};//创建一个链表,拥有N个节点,尾插法
struct Node * CreateList(int N)
{struct Node *pHead = NULL;struct Node *pTail = NULL;for(size_t i=0; i<N; i++){struct Node *pNode = (struct Node *)malloc(sizeof(struct Node));sprintf(pNode -> name,"学生%d",i+1);pNode -> next = NULL;if(pHead == NULL)pHead = pNode;elsepTail -> next = pNode;pTail = pNode;}return pHead;//返回链表头结点的指针
}//打印一条链表
void PrintLinst(struct Node *pHead)
{while(pHead!=NULL){printf("%s  ",pHead -> name);pHead = pHead -> next;//pHead的改变不影响实参,因为是参数的拷贝}printf("\n");
}//根据删除指定学生名字的节点
struct Node * DeleteNodeByName(struct Node *pHead,const char *name)
{//第一步,找到要删除的节点的前一个节点struct Node *pTemp = pHead;struct Node *pLast = NULL;//保存前一个节点while(pTemp){if(strcmp(pTemp -> name,name)==0)break;//找到了就跳出循环,此刻Temp指向了要跳出的节点pLast = pTemp;pTemp = pTemp -> next;//指向下一个}if(pTemp != NULL){printf("找到了要删除的节点:%s\n",pTemp -> name);printf("找到了要删除的节点的前一个:%s\n",pLast -> name);if(pLast == NULL)//说明删除的是头结点{pHead = pTemp -> next;delete pTemp;}else{//让删除节点的前一个的next指向删除节点的下一个地址pLast -> next = pTemp -> next;//删除当前节点的内存free(pTemp);}}elseprintf("未找到了要删除的节点!\n");return pHead;
};int main()
{struct Node *pHead = CreateList(5);PrintLinst(pHead);pHead = DeleteNodeByName(pHead,"学生1");PrintLinst(pHead);return 0;
}

在这里插入图片描述
单项循环链表与单向链表的区别是:尾节点不是NULL,而是指向头结点,从而形成环

单向循环链表

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>struct Node
{char name[32];struct Node *next;
};int main()
{struct Node stu1;struct Node stu2;struct Node stu3;strcpy(stu1.name,"学生A");strcpy(stu2.name,"学生B");strcpy(stu3.name,"学生C");stu1.next = &stu2;stu2.next = &stu3;stu3.next = &stu1;struct Node *pHead = &stu1;struct Node *pTemp = pHead;do{if(pTemp != NULL){printf("%s  ",pTemp -> name);pTemp = pTemp -> next;}}while(pTemp != pHead);printf("\n");return 0;
}

在这里插入图片描述
向单向循环链表的尾部插入结点

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

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

相关文章

【EI会议征稿】第十届机电一体化与工业信息学国际学术研讨会(ISMII 2024)

第十届机电一体化与工业信息学国际学术研讨会&#xff08;ISMII 2024&#xff09; 2024 10th International Symposium on Mechatronics and Industrial Informatics 随着往年九届的成功举办&#xff0c;2024年第十届机电一体化与工业信息学国际学术研讨会&#xff08;ISMII…

深入理解Flexbox:构建灵活的布局系统

由于篇幅限制&#xff0c;我将提供一个详细的文章大纲和部分内容。您可以根据这个大纲扩展文章内容&#xff0c;以满足3000字的要求。 深入理解Flexbox&#xff1a;构建灵活的布局系统 引言 在现代web设计中&#xff0c;创建灵活且响应式的布局是非常重要的。Flexbox&#xf…

Google DeepMind推出大模型 Gemini (vs GPT4):规模最大、能力最强的人工智能模型

系列文章目录 文章目录 系列文章目录前言谷歌和 Alphabet 首席执行官桑达尔-皮查伊&#xff08;Sundar Pichai&#xff09;的说明一、Gemini 介绍二 、最先进的性能三、新一代功能四、复杂的推理能力五、理解文本、图像、音频及其他内容六、先进的编码技术七、更可靠、可扩展、…

推荐一个可以记录历史进价的进销存软件?

“我是卖数码产品的&#xff0c;数码产品价格变动是比较大的&#xff0c;每次采购时候我都会多家对比价格&#xff0c;再决定在哪个厂家进货。所以基本上我每次进价价格都不一样&#xff0c;但是之前的询价情况又很难一一单独记录&#xff0c;让我采购的时候很被动。” “准备…

java--枚举

1.枚举 枚举是一种特殊类 2.枚举类的格式 注意&#xff1a; ①枚举类中的第一行&#xff0c;只能写一些合法的标识符(名称)&#xff0c;多个名称用逗号隔开。 ②这些名称&#xff0c;本质是常量&#xff0c;每个常量都会记住枚举类的一个对象。 3.枚举类的特点 ①枚举类的…

预测:2024年的安防监控行业将迎来怎样的变化?

随着科技的飞速发展&#xff0c;安防监控视频技术已经成为我们生活中的重要部分。通过对其发展趋势的深入了解&#xff0c;我们可以对未来做出更为精确的预测。本文将探讨2024年安防监控视频技术的可能发展趋势。 1、5G技术的普及将加速安防视频监控技术的发展 5G的高速率、低…

背包问题学习

背包问题是常见的动态规划dp的问题 下面用到的符号: 常用n表示物品数, m表示背包容积f[i][j]表示i件物品, j的背包容量的最大价值w[i]表示第i件物品的价值, v[i] 表示第i件物品的容量f[0][0~m] 0, 所以n可以从1开始遍历一般是有两层嵌套循环 第一层遍历物品, 第二层遍历背包…

PHP使用HTTP代码示例模板

PHP是一种广泛用于服务器端的编程语言&#xff0c;它提供了许多内置的函数和扩展&#xff0c;以便开发人员能够轻松地处理HTTP请求和响应。在PHP中&#xff0c;您可以使用以下代码示例模板来处理HTTP请求和生成HTTP响应。 php复制代码 <?php // 处理GET请求 if ($…

获取Github Copilot的Token

可以在线提取出Github Copilot插件的Token&#xff0c;这样的话就可以把Token拿来做别的用处了&#xff0c;比如共享给其他人 Github Copilot是一款由GitHub和OpenAI合作开发的人工智能编程助手。它利用机器学习和自然语言处理技术&#xff0c;能够根据用户的输入自动生成代码…

IDEA中配置Git

Git 在IDEA中使用Git1 在IDEA中配置Git2 在IDEA中使用Git2.1在IDEA中创建工程并将工程添加至Git2.2 将文件添加到暂存区2.3 提交文件2.4 将代码推送到远程仓库2.5 从远程仓库克隆工程到本地2.6 从远程拉取代码2.7 版本对比2.8 创建分支2.9 切换分支2.10 分支合并 3 使用IDEA进行…

数据结构与算法编程题49

假设不带权有向图采用邻接表G存储&#xff0c;设计实现以下功能的算法。 &#xff08;1&#xff09;求出图中每个顶点的出度。 &#xff08;2&#xff09;求出图中出度为0的顶点数。 &#xff08;3&#xff09;求出图中每个顶点的入度。 #include <iostream> using names…

私域最全养号攻略---微信

微信号的使用规则&#xff1a; 注册新微信、微信实名认证、主动添加好友、面对面建群、被动添加好友、进群限制、朋友圈限制、好友上限 微信权重加分规则&#xff1a; 基础信息是否完整、注册时间、微信使用行为、 微信权重扣分规则&#xff1a; 使用的环境是否正常、部分行为会…

Michael.W基于Foundry精读Openzeppelin第40期——ERC20Burnable.sol

Michael.W基于Foundry精读Openzeppelin第40期——ERC20Burnable.sol 0. 版本0.1 ERC20Burnable.sol 1. 目标合约2. 代码精读2.1 burn(uint256 amount)2.2 burnFrom(address account, uint256 amount) 0. 版本 [openzeppelin]&#xff1a;v4.8.3&#xff0c;[forge-std]&#x…

1.pipenv创建pyqt5虚拟环境

pipenv创建pyqt5虚拟环境 一、安装pipenv ​ cmd输入指令&#xff1a; pip install pipenv二、安装虚拟环境 cmd进入我要创建环境的目录下 我使用以下命令在当前目录下创建虚拟环境&#xff1a; pipenv --python 3.8创建一个基于Python 3.8的虚拟环境&#xff0c;并生成一个…

华为鸿蒙开发——开发及引用静态共享包(HAR)、应用配置文件

文章目录 简述一、创建HAR模块二、编译HAR模块三、应用配置文件&#xff08;Stage模型&#xff09;四、应用配置文件&#xff08;FA模型&#xff09;1、配置文件的内部结构&#xff08;1&#xff09;app&#xff08;2&#xff09;deviceConfig&#xff08;3&#xff09;module …

C - 语言->内存函数

目录 系列文章目录 前言 1. memcpy使⽤和模拟实现 1.2 memcpy函数的模拟实现: 2. memmove 使⽤和模拟实现 2.1memmove的模拟实现&#xff1a; 3. memset 函数的使⽤ 4. memcmp 函数的使⽤ 系列文章目录 ✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff…

uniapp实战 —— 猜你喜欢(含滚动触底分页加载)

效果预览 组件封装 src\components\SUI_Guess.vue <script setup lang"ts"> import { ref, onMounted } from vue import type { GuessItem } from /types/index import { getGuessListAPI } from /apis/index import type { PageParams } from /types/global…

如何使用技术 SEO 优化 Pinterest 富图钉

Pinterest 可以影响搜索引擎排名&#xff0c;尤其是谷歌。不过&#xff0c;它的作用方式与其他搜索引擎优化因素不同。这就是 Google 将图钉放在 nofollow 列表中。但是&#xff0c;它们仍然可以作为搜索引擎优化的一个重要因素。 高质量的图钉具有高分辨率的图片、吸引人的内…

(汇川H5U-A8)Modbus Poll与AutoShop使用RS-485通讯

一、初步认识: AutoShop: Modbus Poll: 1、连接配置 ConnectionSerial PortRS-485转串口,所以是串口Serial SettingsCOM3当你插入串口后,会显示新的一个端口,就是这个端口通讯速率9600与PLC协议配置一致数据长度8与PLC协议配置一致奇偶校验位0与PLC协议配置一致停止位2…

用perl解决小朋友问的2的10000次方是多少的问题

2的10000次方是多少&#xff0c;用perl单行命令搞定&#xff0c; perl -Mbigint -le print 2**10000如果是安装了strawberry perl &#xff0c;在Windows控制台上输入&#xff0c;单行命令的单引号要换成双引号。 perl -Mbigint -le "print 2**10000"在git-bash中执…