链表基本操作
单链表简介
单链表结构
头指针是指向链表中第一个结点的指针
首元结点是指链表中存储第一个数据元素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. 参数说明 工作节点瞬间压力大,导致和集群通信出现延迟,被踢出节点,瞬间释放的连接立即又连接到另外节点,最终集群挂掉。加了一些延迟配置后…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
