链表基本操作
单链表简介
单链表结构
头指针是指向链表中第一个结点的指针
首元结点是指链表中存储第一个数据元素a1的结点
头结点是在链表的首元结点之前附设的一个结点;数据域内只放空表标志和表长等信息
单链表存储结构定义:
typedef struct Lnode
{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
// *LinkList为Lnode类型的指针
单链表基本操作
#include <stdlib.h>
#include <stdio.h>#define OK 1
#define FALSE 0
#define ERROR -1
#define OVERFLOW -2typedef int Status;
typedef int ElemType;typedef struct LNode //链表结点定义
{ElemType Data; //结点的数据域struct LNode *Next; //结点的指针域
}LNode, *LinkList;//功能:初始化单链表,即生成只有表头的单链表,成功返回OK,否则返回ERROR
Status InitLinkList_L(LinkList &L)
{L = (LinkList)malloc(sizeof(LNode)); //生成头结点if(L){L->Next = NULL; //头结点的next指针为空return OK;}elsereturn ERROR;
}//功能:向单链表中输入n个数据,成功返回OK,否则返回ERROR
Status InputData_L(LinkList &L, int n)
{int i;LinkList p;printf("链表建立方法:头插法!\n");for(i = 1; i <= n; i++){printf("第 %d 个数据:", i);p = (LinkList)malloc(sizeof(LNode)); //生成新的数据结点if(p){scanf("%d", &(p->Data));p->Next = L->Next; //插入位置为头结点后面,因此p的指针为头结点指针L->Next = p; //头结点指针指向新的数据结点}elsereturn ERROR;}return OK;
}//功能:查询链表L的第i个位置上是否存在元素,存在返回OK,否则返回ERROR,找到的数据存放到变量e中
Status GetElem_L(LinkList L, int i, ElemType &e)
{LinkList p;int j;p = L->Next; j = 1;while(p&&(j<i)){p = p->Next;j++;}if(!p || j > i)return ERROR;e = p->Data;return OK;
}//功能:向链表L的第i个位置插入一个数据e,插入成功返回OK,否则返回ERROR
Status ListInsert_L(LinkList &L, int i, ElemType e)
{LinkList p, s;int j;p = L;j = 0;while(p &&(j < i - 1)){p = p->Next;j++;}if(!p || j > i)return ERROR;s = (LinkList)malloc(sizeof(LNode));s->Data = e;s->Next = p->Next;p->Next = s;return OK;
}//功能:将链表L的第i个位置删除,删除的值保存到e,删除成功返回OK,否则返回ERROR
Status ListDelete_L(LinkList &L, int i, ElemType &e)
{LinkList p, q;int j;p = L; j = 0;while(p->Next && (j < i-1)){p = p->Next;j++;}if(!(p->Next) || (j > i - 1))return ERROR;q = p->Next;p->Next = q->Next;e = q->Data; free(q); //删除后,释放对应数据的空间return OK;
}//功能:求链表L的长度,返回链表L的长度
int ListLength_L(LinkList L)
{int j = 0;LinkList p = L;while(p->Next){p = p->Next;j++;}return j;
}//功能:依次输出链表L的每个数据
void OutputList_L(LinkList L)
{LinkList p;int j = 0; //计数器p = L->Next;while(p){j++;printf("第 %d 个数据为:", j);printf("%d\n", p->Data);p = p->Next;}if(j == 0)printf("\n空链表,数据总个数为 0 .\n");elseprintf("\n链表数据总数为:%d\n", j);
}//功能:依次清除链表L的每个数据,并释放相应的空间,清除成功,返回OK,否则ERROR
Status ClearLis_L(LinkList &L)
{LinkList p, q;p = L->Next; if(!p){printf("链表为空,无需清除!\n");return OK;}printf("正在清除链表L中的数据,请等待...\n");while(p) //链表非空{q = p; //p = q->Next;free(q);}L->Next = NULL;printf("链表L中的数据清除完成!\n");return OK;
}void ShowMenu() //主菜单
{ printf("\n");printf("\n****************单链表(头插法)数据操作****************\n\n");printf("\t\t1 链表数据输出\n\n");printf("\t\t2 链表数据插入\n\n");printf("\t\t3 链表数据删除\n\n");printf("\t\t4 链表数据查询\n\n");printf("\t\t5 链表数据清空\n\n");printf("\t\t0 退出系统\n\n");printf("****************单链表(头插法)数据操作****************\n");printf("\n");
}//功能:菜单2的操作处理,实现:在单链表的第i个位置插入数据e的操作
void SubMenu2(LinkList &L)
{int i;ElemType e;printf("插入位置:");scanf("%d", &i);printf("插入的数据:");scanf("%d", &e);if(ListInsert_L(L, i, e) == OK)printf("在单链表L的第 %d 位置成功插入数据 %d .\n", i, e);elseprintf("插入位置:%d 错误!\n", i);
}//功能:菜单3的操作处理,实现:在单链表的第i个位置删除数据e的操作
void SubMenu3(LinkList &L)
{//ListDelete_Lint i;ElemType e;printf("删除位置:");scanf("%d", &i);if(ListDelete_L(L, i, e) == OK)printf("在单链表L的第 %d 位置成功删除数据 %d .\n", i, e);elseprintf("删除位置:%d 错误!\n", i);
}//菜单3的操作处理,实现:查询单链表的第i个位置数据的操作
void SubMenu4(LinkList L)
{int i;ElemType e;printf("插入位置:");scanf("%d", &i);if(GetElem_L(L, i, e) == OK)printf("单链表L的第 %d 个位置的数据:%d\n", i, e);elseprintf("单链表L的第 %d 个位置的数据不存在!\n", i);
}void main()
{int choice = 0; //用户功能选择LinkList L;InitLinkList_L(L); //初始化单链表while(1){system("CLS");ShowMenu();printf("Please choose(请选择): ");scanf("%d",&choice);switch(choice){case 1:{OutputList_L(L); //调用输出函数对链表的数据进行输出fflush(stdin);system("pause");break;}case 2:{SubMenu2(L); //调用菜单2功能,实现数据的插入操作fflush(stdin);system("pause");break;}case 3:{SubMenu3(L);fflush(stdin);system("pause");break;}case 4:{SubMenu4(L);getchar(); getchar(); system("CLS");break;}case 5:{ClearLis_L(L);fflush(stdin);system("pause");break;}case 0:{system("CLS");printf("谢谢使用!\n");exit(0);}default:{printf("功能选择错误,只能选择0-5!\n");fflush(stdin);system("pause");}}}
}
单链表创建(尾插法)
#include <stdio.h>
#include <stdlib.h>#define OK 1
#define FALSE 0
#define ERROR -1
#define OVERFLOW -2typedef int ElemType;//单链表结点结构定义
typedef struct LNode
{ ElemType data; //每个结点实际存放的数据—数据域struct LNode *next; //下一个结点的地址—指针域
}LNode, *LinkList;int CreateList(LinkList &L, int n)
{int i;LinkList tail, p;L = (LinkList) malloc (sizeof (LNode));if(!L)return ERROR;L->next = NULL;tail = NULL;for(i = 1; i <= n; i++){p = (LinkList) malloc (sizeof (LNode));if(!p)return ERROR;printf("\n\n第%d个数据为:", i);scanf("%d", &p->data); // 输入元素值p->next = NULL;if(i == 1)L->next = p;elsetail->next = p;tail = p;}return OK;
}void TransverList(LinkList L)
{LinkList p;int j;p = L->next; j = 0;while(p){j++;printf("第%d个数据为:", j);printf("%d\n\n", p->data);p = p->next;}
}void main()
{LinkList L;int n;printf(" *******************************************************************\n\n");printf(" 创建链表——尾插法\n\n");printf(" *******************************************************************\n\n");printf("数据个数:");scanf("%d", &n);CreateList(L, n);printf("\n\n链表中的数据浏览结果\n\n");TransverList(L);
}
静态链表
#include <stdio.h>
#include <stdlib.h>#define OK 1
#define FALSE 0
#define ERROR -1
#define OVERFLOW -2
#define MAXSIZE 10 // 静态链表的最大长typedef int Status;
typedef int ElemType;struct Component //静态链表的结点结构定义
{ElemType data;int cur; //相对地址,相对于0号位置的地址,实际上就是数组的下标
};//功能:实现静态链表的初始化操作,初始化成功,返回OK
Status InitStaticList(Component VList[ MAXSIZE + 1])
{int i;VList[0].cur = -1; //置该静态链表为空链表for(i = 1; i <= MAXSIZE; i++) //置该静态链表的每个空间都可以存放数据VList[i].cur = 0; //每个空间的cur为0表示该空间可以存放数据,否则表示该空间已经存放数据return OK;
}//功能:实现静态链表数据的全部输出
void OutputStaticList( Component VList[MAXSIZE + 1])
{int i = 0, k = 1;if( VList[0].cur == -1)printf("\n 静态链表为空,无数据!\n");else{printf("\n静态链表中的数据为:");i = 0;while( VList[i].cur != -1){printf("第 %d 数据为:%d\n", k, VList[VList[i].cur].data);i = VList[i].cur; k++;}}
}//功能:实现静态链表数据的插入,插入数据是在尾部插入(也可实现在第i个位置插入数据),成功返回1,否则,返回0
Status InsertStaticList(Component VList[MAXSIZE + 1], ElemType e)
{int i = 0, pos = 0;if(VList[0].cur == -1) //空表时,插入数据的位置为1号位置pos = 1;else //非空表,插入的位置不清楚,因此需检索哪个空闲,就写入到该空间{for(i = 1; i <= MAXSIZE; i++) //寻找第一个可插入位置if( VList[i].cur == 0)break;if( i >= MAXSIZE) //空间全部全部使用,则无插入位置return ERROR; elsepos = i; //将插入位置赋给pos}if(VList[0].cur == -1) //空表时,插入数据的位置为1号位置i = 0;else{for(i = 1; i <= MAXSIZE; i++) //寻找链表的最后一个数据位置if( VList[i].cur == -1)break;if( i>= MAXSIZE)return ERROR;}if( pos == 0)return 0;else{VList[pos].data = e;VList[i].cur = pos;VList[pos].cur = -1;return OK;}
}//功能:实现静态链表数据的删除,删除成功,则返回该数据在静态链表中的位置,否则返回0
int DeleteStaticList(Component VList[MAXSIZE + 1], ElemType e)
{int i = 0, k = 1;if(VList[i].cur == -1) //空的静态表,不能删除数据return 0;while(VList[VList[i].cur].data != e)i = VList[i].cur;if( i == -1) //没找到return 0;else //找到,i存储的是被删除元素的前驱{k = VList[i].cur;VList[i].cur = VList[k].cur;VList[k].cur = 0; //该位置空出,可以写入新的数据}return OK;
}//功 能:实现静态链表数据的查询,成功返回该数据在链表中的位置,否则,返回0
int SearchStaticList(Component VList[MAXSIZE + 1], ElemType e)
{int i = 0;if(VList[0].cur = -1)return 0;i = 1;while(VList[i].cur != -1) //注意:不能按数组的方式从上到下扫描,不然可能找到以前的数据。必须按链表的方式进行扫描if(VList[i].data != e)i = VList[i].cur;if( i == -1) //没找到return 0;elsereturn i; //找到返回其所在的下标
}void ShowMenu() //主菜单
{ printf("\n");printf("\n****************静态链表基本操作****************\n\n");printf("\t\t1 静态链表初始化\n\n");printf("\t\t2 静态链表数据显示\n\n");printf("\t\t3 静态链表数据插入\n\n");printf("\t\t4 静态链表数据删除\n\n");printf("\t\t5 静态链表数据查询\n\n");printf("\t\t0 退 出(exit)\n\n");printf("****************静态链表基本操作****************\n");printf("\n");
}void main()
{int choice = 0; //功能选项ElemType e;Component VList[MAXSIZE + 1];InitStaticList(VList); //初始化while(1){system("CLS");ShowMenu();printf("Please choose: ");scanf("%d",&choice);switch(choice){case 1:{printf("严重警告:重新初始化静态链表,会使原有数据丢失!\n");if (InitStaticList(VList) == 1)printf("\n静态链表初始化成功!\n\n");fflush(stdin);system("pause");break;}case 2:{OutputStaticList(VList);fflush(stdin);system("pause");break;}case 3:{printf("插入数据:");scanf("%d", &e);InsertStaticList(VList, e);fflush(stdin);system("pause");break;}case 4:{printf("删除数据:");scanf("%d", &e);DeleteStaticList(VList, e);fflush(stdin);system("pause");break;}case 5:{printf("查询数据:");scanf("%d", &e);InsertStaticList(VList, e);fflush(stdin);system("pause");break;}case 0:{system("CLS");printf("Thanks for using!\n");exit(0);}default:{printf("功能选择错误,只能选择0-5!\n");fflush(stdin);system("pause");}}}
}
相关文章:

链表基本操作
单链表简介 单链表结构 头指针是指向链表中第一个结点的指针 首元结点是指链表中存储第一个数据元素a1的结点 头结点是在链表的首元结点之前附设的一个结点;数据域内只放空表标志和表长等信息 单链表存储结构定义: typedef struct Lnode { ElemTyp…...

Linux学习笔记-Ubuntu系统下配置用户ssh只能访问git仓库
目录 一、基本信息1.1 系统信息1.2 git版本[^1]1.2.1 服务器端git版本1.2.2 客户端TortoiseGit版本1.2.3 客户端Git for windows版本 二、创建git用户和群组[^2]2.1 使用groupadd创建群组2.2 创建git用户2.2.1 使用useradd创建git用户2.2.2 配置新建的git用户ssh免密访问 2.3 创…...

央媒发稿不能改?媒体发布新闻稿有哪些注意点
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 “央媒发稿不能改”是媒体行业和新闻传播领域的普遍理解。央媒,即中央主要媒体,是权威性的新闻源,当这些媒体发布新闻稿或报道时,其他省、…...

计算机竞赛 深度学习 opencv python 公式识别(图像识别 机器视觉)
文章目录 0 前言1 课题说明2 效果展示3 具体实现4 关键代码实现5 算法综合效果6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的数学公式识别算法实现 该项目较为新颖,适合作为竞赛课题方向,学…...

KPM算法
概念 KMP(Knuth–Morris–Pratt)算法是一种字符串匹配算法,用于在一个主文本字符串中查找一个模式字符串的出现位置。KMP算法通过利用模式字符串中的重复性,避免无意义的字符比较,从而提高效率。 KMP算法的核心思想是…...

全流程GMS地下水数值模拟及溶质(包含反应性溶质)运移模拟技术教程
详情点击公众号链接:全流程GMS地下水数值模拟及溶质(包含反应性溶质)运移模拟技术教程 前言 GMS三维地质结构建模 GMS地下水流数值模拟 GMS溶质运移数值模拟与反应性溶质运移模 详情 1.GMS的建模数据的收集、数据预处理以及格式等ÿ…...

GE D20 EME 10BASE-T电源模块产品特点
GE D20 EME 10BASE-T 电源模块通常是工业自动化和控制系统中的一个关键组件,用于为系统中的各种设备和模块提供电源。以下是可能包括在 GE D20 EME 10BASE-T 电源模块中的一些产品特点: 电源输出:D20 EME 模块通常提供一个或多个电源输出通道…...

游戏工作时d3dcompiler_47.dll缺失怎么修复?5种修复方法分享
游戏提示 d3dcompiler_47.dll 缺失的困扰,相信许多玩家都遇到过。这种情况通常会导致游戏无法正常运行,给玩家带来很大的不便。那么,该如何解决这个问题呢?小编将为大家介绍几种解决方法,希望对大家有所帮助。 首先&am…...

关于激光探测器光斑质心算法在FPGA硬件的设计
目录 0引言 1CCD采集图像质心算法 2基于FPGA的图像质心算法 3仿真结果与分析 4结论 0引言 在一些姿态检测的实际应用中,需要在被测对象上安装激光探测器[1],利用CCD相机捕捉激光光斑来检测观测对象的实际情况,光斑图像质心坐标的提取是图…...

理清SpringBoot CURD处理逻辑、顺序
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 理清SpringBoot CURD处理逻辑、顺序 Controller(控制器): 控制器接收来自客户端的请求,并负责处理请求的路由和参数解析…...
缓存读写淘汰算法W-TinyLFU算法
在W-TinyLFU中,每个缓存项都会被赋予一个权重。这个权重可以表示缓存项的大小、使用频率、是否是热数据等因素。每次需要淘汰缓存时,W-TinyLFU会选择小于一定阈值的权重的缓存项进行淘汰,以避免淘汰热数据。 另外,W-TinyLFU也会根…...

C++中的 throw详解
在《C++异常处理》一节中,我们讲到了 C++ 异常处理的流程,具体为: 抛出(Throw)--> 检测(Try) --> 捕获(Catch) 异常必须显式地抛出,才能被检测和捕获到;如果没有显式的抛出,即使有异常也检测不到。在 C++ 中,我们使用 throw 关键字来显式地抛出异常,它的用…...
vue 封装Table组件
基于element-plus UI 框架封装一个table组件 在项目目录下的components新建一个Table.vue <template><section class"wrap"><el-tableref"table":data"tableData" v-loading"loading" style"width: 100%":…...
MySQL主从复制错误
当在MySQL的多线程复制中遇到错误时,你可能会看到上述的错误信息。错误的核心在于从服务器上的工作线程在尝试执行一个特定的事务时遇到了问题。 为了解决这个问题,你可以采取以下步骤: 查看MySQL的错误日志:错误日志可能会提供更…...
Redis群集
目录 1、redis群集三种模式 2、Redis 主从复制 2.1 主从复制的作用 2.2 主从复制流程 2.3 搭建Redis 主从复制 3、Redis 哨兵模式 3.1 哨兵模式的作用 3.2 故障转移机制 3.3 主节点的选举 4、Redis 群集模式 4.1 集群的作用 4.2 Redis集群的数据分片 4.3 搭建Redis…...

Spring AOP以及统一处理
一.Spring AOP 1.什么是Spring AOP AOP(Aspect Oriented Programming):面向切面编程,它是一种思想,它是对某一类事情的集中处理。 2.AOP的作用 想象一个场景,我们在做后台系统时,除了登录…...

vue2markdown转思维导图
官网 http://markmap.js.org 按照官网安装markmap-lib,markmap-view两个依赖外,还需要安装markmap-common 如果报错提示vuePdfNoSss相关问题,需要安装vue-pdf 如果报错can’t import the named export ‘xxx’ from non EcmaScript module,需…...

docker下redis备份文件dump.rdb获取
1.查看镜像 docker ps -a 2.进入redis客户端 docker exec -it redis redis-cli 3.保存备份文件 save 4.查看文件存放位置 CONFIG GET dir 5.将docker中文件拷出 docker cp id或name:容器中文件的路径 目标目录地址...

二十一、MySQL(多表)内连接、外连接、自连接实现
1、多表查询 (1)基础概念: (2)多表查询的分类: 2、内连接 (1)基础概念: (2)隐式内连接: 基础语法: select 表1.name,…...
Zookeeper运维
我是一个目录 1. 参数说明2. Zookeeper优化建议3. Zookeeper性能查看4. 建议 1. 参数说明 工作节点瞬间压力大,导致和集群通信出现延迟,被踢出节点,瞬间释放的连接立即又连接到另外节点,最终集群挂掉。加了一些延迟配置后…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...

aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...
Windows 下端口占用排查与释放全攻略
Windows 下端口占用排查与释放全攻略 在开发和运维过程中,经常会遇到端口被占用的问题(如 8080、3306 等常用端口)。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口,帮助你高效解决此类问题。 一、准…...

动态规划-1035.不相交的线-力扣(LeetCode)
一、题目解析 光看题目要求和例图,感觉这题好麻烦,直线不能相交啊,每个数字只属于一条连线啊等等,但我们结合题目所给的信息和例图的内容,这不就是最长公共子序列吗?,我们把最长公共子序列连线起…...