单链表操作 C实现
struct LNode { //定义一个节点
int data; //数据域
struct LNode *next; //指针域
};
0.初始化
typedef sturct LNode{ //定义单链表结点类型 int date ; //每个结点存放一个数据元素struct LNode *next; //指针指向下一个结点
}LNodes, *LinkList;
typedef LNode{ //定义单链表结点类型 int date ; //每个结点存放一个数据元素struct LNode *next; //指针指向下一个结点
};//typedef struct LNode LNodes;
//typedef struct LNOde *LinkList;
//上面俩个是等价的1)不带头结点的单链表
bool InitList(LinkList &L) //初始化空链表
{L = NULL; //空表没有任何结点return true;
}void test()
{LinkList L ; //声明一个指向单链表的指针//初始化一个空表InitList (L);
}判断是否为空
bool Empty(LinkList L){if(L == NULL)return true;else return false;
}
//或:
bool Empty(LinkList L){return (L == NULL);
}2)带头节的单链表
//初始化一个单链表(带头结点)
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;
}
1.尾插法建立链表
struct LNode *CreateLinkList1(void){ //尾插法创建链表struct LNode *head=(struct LNode *)malloc(LEN); //创建一个头节点head->next=NULL; //开始时头节点指针指向NULLstruct LNode *h=head,*s;struct LNode info;//接收从键盘输入每个节点的数据scanf("%d",&info.data);while(info.data!=0){ //创建链表,直到输入数据为0结束s=(struct LNode *)malloc(LEN);s->data=info.data; //节点s接收输入数据h->next=s; //尾插如链表尾部h=h->next; //保持h位于链表末尾,方便接收下一个节点数据scanf("%d",&info.data);}h->next=NULL; //链表末尾指向NULLreturn head;
}
typedef struct LNode {int data; //数据域struct LNode *next; //指针域}LNodes,*LinkList;LNodes *insertFront(LNodes *head, LNodes *newNode)
{newNode->next = head->next;head->next = newNode;return head;
}
2.头插法建立链表
struct LNode *CreateLinkList2(void){ //头插法创建链表struct LNode *head=(struct LNode *)malloc(LEN);head->next=NULL;struct LNode *h=head,*s;struct LNode info;scanf("%d",&info.data);while(info.data!=0){ //创建链表,直到输入数据为0结束s=(struct LNode *)malloc(LEN);s->data=info.data;//节点s接收输入数据s->next=h->next; //头插插入头节点尾部,插入节点要始终跟着头节点后面h->next=s; scanf("%d",&info.data);}return head;
}
typedef struct LNode {int data; //数据域struct LNode *next; //指针域}LNodes,*LinkList;LNodes *insertBack(LNodes *head, LNodes *tail, LNodes *newNode)
{newNode->next = NULL;tail->next = newNode;tail = newNode;return head;
}
3.链表结点删除操作
struct LNode *Delete(struct LNode *head,int x){ //删除链表中值为x的节点struct LNode *p=head->next,*pre=head,*q;while(p!=NULL){if(p->data==x){q=p;pre->next=p->next;p=p->next;free(q);}else{pre=p;p=p->next;}}return head;
}
4.在有序链表中插入一个结点
struct LNode *Insert(struct LNode *head,int x){ //创建一个递增链表,将x插入链表,并保持有序struct LNode *p=head->next,*pre=head,*q;while(p!=NULL){if(x<p->data){q=(struct LNode *)malloc(LEN); //为插入值分配一个节点空间q->data=x;pre->next=q;q->next=p;break;}else{pre=p;p=p->next;}}return head;
}
5.遍历
void print(struct LNode *head){ //遍历链表并输出各个节点的数据struct LNode *p=head->next;while(p!=NULL){printf("%d->",p->data);p=p->next;}printf("NULL\n");
}
运行程序结果:
尾插法:1 2 3 4 6 7 8 9 0
1->2->3->4->6->7->8->9->NULL
头插法:1 2 3 4 6 7 8 9 0
9->8->7->6->4->3->2->1->NULL
删除节点8:1->2->3->4->6->7->9->NULL
插入节点5:1->2->3->4->5->6->7->9->NULL
Press any key to continue...
完整的代码如下:
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct LNode) //LEN表示一个节点大小
struct LNode{ //定义一个节点int data; //数据域struct LNode *next; //指针域
};
struct LNode *CreateLinkList1(void){ //尾插法创建链表struct LNode *head=(struct LNode *)malloc(LEN); //创建一个头节点head->next=NULL; //开始时头节点指针指向NULLstruct LNode *h=head,*s;struct LNode info;//接收从键盘输入每个节点的数据scanf("%d",&info.data);while(info.data!=0){ //创建链表,直到输入数据为0结束s=(struct LNode *)malloc(LEN);s->data=info.data; //节点s接收输入数据h->next=s; //尾插如链表尾部h=h->next; //保持h位于链表末尾,方便接收下一个节点数据scanf("%d",&info.data);}h->next=NULL; //链表末尾指向NULLreturn head;
}
struct LNode *CreateLinkList2(void){ //头插法创建链表struct LNode *head=(struct LNode *)malloc(LEN);head->next=NULL;struct LNode *h=head,*s;struct LNode info;scanf("%d",&info.data);while(info.data!=0){ //创建链表,直到输入数据为0结束s=(struct LNode *)malloc(LEN);s->data=info.data;//节点s接收输入数据s->next=h->next; //头插插入头节点尾部,插入节点要始终跟着头节点后面h->next=s; scanf("%d",&info.data);}return head;
}
struct LNode *Delete(struct LNode *head,int x){ //删除链表中值为x的节点struct LNode *p=head->next,*pre=head,*q;while(p!=NULL){if(p->data==x){q=p;pre->next=p->next;p=p->next;free(q);}else{pre=p;p=p->next;}}return head;
}
struct LNode *Insert(struct LNode *head,int x){ //创建一个递增链表,将x插入链表,并保持有序struct LNode *p=head->next,*pre=head,*q;while(p!=NULL){if(x<p->data){q=(struct LNode *)malloc(LEN); //为插入值分配一个节点空间q->data=x;pre->next=q;q->next=p;break;}else{pre=p;p=p->next;}}return head;
}
void print(struct LNode *head){ //遍历链表并输出各个节点的数据struct LNode *p=head->next;while(p!=NULL){printf("%d->",p->data);p=p->next;}printf("NULL\n");
}
int main(void){struct LNode *p1,*p2,*q,*y;printf("尾插法:");p1=CreateLinkList1(); //p1接收尾插法传回的头节点print(p1);printf("头插法:");p2=CreateLinkList2(); //p2接收头插法传回的头节点print(p2);printf("删除节点8:");q=Delete(p1,8);print(p1);printf("插入节点5:");y=Insert(p1,5);print(y);
}
头插法和尾插法详解
头插法
核心代码:
head->next = NULL;
s->next = head->next;
head->next = s;
单个结点
原始状态
第一个元素插入的过程(注意:1和2的顺序不能颠倒,不然会导致链表缺失)
第一个元素插入后
第二个元素插入的过程(其余元素插入的过程也类似)
第二个元素插入后
尾插法
核心代码:
tail = head;
s->next = NULL;
tail->next = s;
tail = s;
原始状态
第一个元素插入的过程(注意:2和3的顺序不能颠倒,不然会导致链表的生成出错)
第一个元素插入后
第二个元素插入的过程(其余元素插入的过程也类似)
第二个元素插入后
头插法和尾插法的对比
头插法建立链表的算法简短易懂,但是生成链表的结点顺序与原来输入的顺序相反,而用尾插法建立链表可使输入和生成的结点顺序相同
为什么会这样呢?
根据上面的头插法和尾插法的算法,我们很容易知道,当用头插法依次插入值分别为1,2,3,4,5的结点(也叫做元素)后,单链表会如下图所示:
但是用尾插法同样插入值分别为1,2,3,4,5的结点后,单链表却会如下图所示:
而在这两个链表中,输出链表中各个元素的值只能从已知的头结点head开始遍历,所以分别用头插法和尾插法创建链表后,依次输出的元素的值刚好是相反的
验证小例子:
#include <stdio.h>
#include <malloc.h>typedef struct node
{struct node* next;int data;}LinkList; //定义LinkList为struct node类型,即struct node可直接用LinkList来表示,方便定义//头插法创建单链表
int main (void)
{int i, len = 5;
//len表示链表的长度 LinkList* head, * s;
//head为LinkList*类型的指针变量,表示头指针head = (LinkList*)malloc (sizeof (LinkList));
//malloc (sizeof (LinkList))意思是让系统分配内存大小为sizeof (LinkList)的空间head->next = NULL;
//令头指针的所指向结点的指针域为空for (i = 0; i < len; i++){s = (LinkList*)malloc (sizeof (LinkList));printf ("请输入该元素的值:");scanf ("%d", &s->data);s->next = head->next;head->next = s;}
//以下代码是为了将单链表中各个元素的值依次打印出来 LinkList* q;q = (LinkList*)malloc (sizeof (LinkList));q = head->next;while (q != NULL){printf ("%d", q->data);q = q->next;}return 0;
}
结果:
请输入该元素的值:1
请输入该元素的值:2
请输入该元素的值:3
请输入该元素的值:4
请输入该元素的值:5
54321
#include <stdio.h>
#include <malloc.h>typedef struct node
{struct node* next;int data;}LinkList; //尾插法创建单链表
int main (void)
{int i, len = 5;LinkList* head,* s,* tail;
//tail表示尾指针 head = (LinkList*)malloc (sizeof (LinkList));tail = head;for (i = 0; i < len; i++){s = (LinkList*)malloc (sizeof (LinkList));printf ("请输入该元素的值:");scanf ("%d", &s->data); s->next = NULL;tail->next = s;tail = s;}//以下代码是将单链表中各个元素的值依次打印出来 LinkList* q;q = head->next;while (q != NULL){printf ("%d", q->data);q = q->next;}return 0;}
结果:
请输入该元素的值:1
请输入该元素的值:2
请输入该元素的值:3
请输入该元素的值:4
请输入该元素的值:5
12345
————————————————
相关文章:

单链表操作 C实现
struct LNode { //定义一个节点 int data; //数据域 struct LNode *next; //指针域 }; 0.初始化 typedef sturct LNode{ //定义单链表结点类型 int date ; //每个结点存放一个数据元素struct LNode *next; //指针指向下…...

WordPress主题网站首页添加好看的四格小工具教程
直接到网站根目录创建一个css文件(文件名:sige.css),文件名可自定义(注意文件名一致) <link rel"stylesheet" href"你的网站/sige.css" type"text/css" > 然后在header.php模板最上方添加引入代码 也可自定义HTML里添加css代码最上方写…...

unittest自动化测试框架讲解以及实战
为什么要学习unittest 按照测试阶段来划分,可以将测试分为单元测试、集成测试、系统测试和验收测试。单元测试是指对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,通常指函数或者类,一般是开发完成的。 单元…...

数学建模之Matlab基础操作
作者由于后续课程也要学习Matlab,并且之前也进行了一些数学建模的练习(虽然是论文手),所以花了几天零碎时间学习Matlab的基础操作,特此整理。 基本运算 a55 %加法,同理减法 b2^3 %立方 c5*2 %乘法 x 1; …...
【Nuxt】04 Nuxt2-SEO: sitemap.xml、seo优化、robots.txt
1 SiteMap设置 环境准备 注意生成sitemap依赖于nuxtjs/sitemap,并且需要用axios进行请求,不要使用nuxtjs/axios,不然会报错 sitemap.xml配置 在nuxt.config.js中配置下面的内容 npm install nuxtjs/sitemap npm install axios在static/s…...

VMware VSAN 入门
一、虚拟化的存储 1.1、对于数据中心来说最重要的是数据,而承载数据的设备就是存储设备(Storage) 1.2、物理服务器的本地存储阵列 与 虚拟化服务器的本地存储阵列 对比 1.3、避免单台服务器故障的虚拟化高级特性:vSphere HA技术 …...

【设计模式】备忘录模式
文章目录 1.备忘录模式定义2.备忘录模式的角色3.备忘录模式实现3.1.场景说明3.2.结构类图3.3.代码实现 4.备忘录模式优缺点5.备忘录模式适用场景6.备忘录模式总结 主页传送门:💁 传送 1.备忘录模式定义 备忘录(Memento Pattern)模…...
vue3+elementUiPlus表格导出功能
1.下载需要的组件包 npm install file-saver xlsx 2.页面中导入 import FileSaver from file-saver import * as XLSX from xlsx; 3.页面中的表格加一个id <el-table :data"tableData" ref"multipleTableRef" style"width…...

专题五:优先级队列
"你了解我,最干净的轮廓, 握住小小风车和放肆的梦~" 堆是一个不错的数据结构,而在计算机中,无法表示二叉分支结构,因此我们经常会看到使用线性表来作为堆的存储容器。在接触堆的时候,我们是把它…...

游戏设计模式专栏(一):工厂方法模式
引言 大家好,我是亿元程序员,一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》,让糟糕的代码在潜移默化中升华,欢迎大家关注分享收藏订阅。 在游戏开发中,代码的组织和结构对于项目的可…...

element中使用el-steps 进度条效果demo(整理)
<template><div class"margin-top20"><!-- align-center 不要居中就去掉 --><!-- process-status 这几个参数值:改变颜色 wait / process / finish / error / --><!-- active 到第几个是绿色 --><el-steps :space&qu…...

038:mapboxGL 旋转地图(rotateTo)
第038个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中旋转地图。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共68行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:https://xiaozhuan…...

java遇到的问题
java遇到的问题 Tomcat与JDK版本问题 当使用Tomcat10的版本用于springmvc借用浏览器调试时,使用JDK8浏览器会报异常。 需要JDK17(可以配置多个JDK环境,切换使用)才可以使用,配置为JAVA_HOME路径,否则&a…...

LLM(二)| LIMA:在1k高质量数据上微调LLaMA1-65B,性能超越ChatGPT
本文将介绍在Lit-GPT上使用LoRA微调LLaMA模型,并介绍如何自定义数据集进行微调其他开源LLM 监督指令微调(Supervised Instruction Finetuning) 什么是监督指令微调?为什么关注它? 目前大部分LLM都是decoder-only&…...
Android AMS——创建Application(七)
与在 App 内部启动一个 Activity 的不同之处在于,点击桌面 Launcher 首次启动一个应用程序的时候,会先去创建一个该应用程序对应的进程,然后执行 ActivityThread 的 main() 方法去创建该应用对应的 Application,然后再去启动首页 Activity。前面已经分析了进程的创建和启动…...

html 边缘融合加载
html 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>边缘融合加载</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {height: 100vh;padding-bottom: 80px;b…...

ElasticSearch - 在 微服务项目 中基于 RabbitMQ 实现 ES 和 MySQL 数据异步同步(考点)
目录 一、数据同步 1.1、什么是数据同步 1.2、解决数据同步面临的问题 1.3、解决办法 1.3.1、同步调用 1.3.2、异步通知(推荐) 1.3.3、监听 binlog 1.3、基于 RabbitMQ 实现数据同步 1.3.1、需求 1.3.2、在“酒店搜索服务”中 声明 exchange、…...

Springboot+vue的企业人事管理系统(有报告),Javaee项目,springboot vue前后端分离项目。
演示视频: Springbootvue的企业人事管理系统(有报告),Javaee项目,springboot vue前后端分离项目。 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的企业人事管理系统,采用M(model&am…...

初识Java 11-1 函数式编程
目录 旧方式与新方式 lambda表达式 方法引用 Runnable 未绑定方法引用 构造器方法引用 函数式接口 带有更多参数的函数式接口 解决缺乏基本类型函数式接口的问题 本笔记参考自: 《On Java 中文版》 函数式编程语言的一个特点就是其处理代码片段的简易性&am…...

【Ambari】银河麒麟V10 ARM64架构_安装Ambari2.7.6HDP3.3.1问题总结
🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的帮助🌸文…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...