【数据结构】 循环单链表的基本操作 (C语言版)

目录

一、循环单链表

1、循环单链表的定义:

2、循环单链表的优缺点:

二、循环单链表的基本操作算法(C语言)  

 1、宏定义

 2、创建结构体

3、循环单链表的初始化 

4、循环单链表的插入

5、求单链表长度

6、循环单链表的清空

7、循环单链表的销毁

8、循环单链表的取值

9、循环单链表的查找

10、循环单链表的删除

11、头插法创建循环链表

12、尾插法创建循环链表

13、输出链表元素

三、循环单链表的基本操作完整代码(C语言)

四、运行结果


一、循环单链表

1、循环单链表的定义:

循环单链表是一种特殊类型的单链表,其特点是链表的最后一个结点的指针域指向整个链表的第一个结点,从而形成一个环状结构。

这种数据结构可以用来存储有序的数据集合,其插入和删除操作可以在平均时间复杂度O(1)内完成,这是其相比单链表的一大优势。循环单链表的操作一般更复杂,因为需要维护环状的结构,并保证对链表的操作满足时间复杂度的要求。

2、循环单链表的优缺点:

优点:

  1. 循环单链表可以高效地执行插入和删除操作,因为不需要像单链表那样从头或尾部开始遍历整个链表。
  2. 循环单链表的空间利用率较高,因为最后一个结点的指针域指向整个链表的第一个结点,从而避免了浪费空间存储空指针。
  3. 循环单链表适合用于处理有序的数据集合,可以快速地执行查找、插入和删除操作。

缺点:

  1. 循环单链表的操作相对复杂,因为需要维护环状的结构,并保证对链表的操作满足时间复杂度的要求。
  2. 在某些情况下,循环单链表可能比单链表更难以理解和实现。

二、循环单链表的基本操作算法(C语言)  

 1、宏定义
#define OK 1
#define ERROR 0typedef char ElemType;
typedef int Status;
 2、创建结构体
typedef struct LNode {ElemType data;struct LNode *next;
} LNode, *LinkList;
3、循环单链表的初始化 
//循环链表初始化
Status InitList(LinkList &head) {head = new LNode;//head->next=NULL;head->next = head;return OK;
}
4、循环单链表的插入
//插入
Status ListInsert(LinkList &head, int i, ElemType e) {LinkList p = head;int j = 0;while (p && (j < i - 1)) {p = p->next;j++;}if (!p || j > i - 1) {return ERROR;}LNode *s = new LNode;s->data = e;s->next = p->next;p->next = s;return OK;
}
5、求单链表长度
//求单链表长度
Status GetLinkListLength(LinkList head) {LinkList p = head->next;int length = 0;while (p != head) {   //p!=NULL          //单链表不为空表时length++;p = p->next;}return length;
}
6、循环单链表的清空
//清空
Status ClearLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L  p!=NULLq = p;p = p->next;delete q;}head->next = head; //链表为空return OK;
}
7、循环单链表的销毁
//销毁
Status DestoryLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L  p!=NULLq = p;p = p->next;delete q;}head->next = NULL;// printf("\n销毁成功\n");return OK;
}
8、循环单链表的取值
//取值
Status GetLinkList(LinkList head, int i, ElemType &e) {LinkList p = head->next;int j = 1;while (p != head && j < i) {  //p != Lp = p->next;j++;}if (p == head) {//p==Lreturn ERROR;}e = p->data;return OK;
}
9、循环单链表的查找
//查找
int LocateLinkListElem(LinkList head, ElemType e) {LinkList p = head->next;int j = 1;while (p != head && (p->data != e)) {//p != L p!=NULLp = p->next;j++;}if (p == head) { //p==L  !p<=>p==NULLreturn 0;}return j;
}
10、循环单链表的删除
//删除
Status ListDelete(LinkList &head, int i, ElemType &e) {LinkList p = head;int j = 0;while (p->next != head && j < i - 1) {  //p != Lp = p->next;j++;}if (p->next == head) { //p==Lreturn ERROR;}LinkList q = p->next;e = q->data;p->next = q->next;delete q;return OK;
}
11、头插法创建循环链表
//头插法创建循环链表
void CreateLinkList_H(LinkList &head, int n) {InitList(head);for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;p->next = head->next;head->next = p;}
}
12、尾插法创建循环链表
//尾插法创建循环链表
void CreateLinkList_R(LinkList &head, int n) {InitList(head);LinkList r = head;for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;//p->next=NULL   p->next=head//p->next = r->next;r->next = p;r = p;}r->next = head;                //尾结点next域指向头结点
}
13、输出链表元素
//输出链表元素
void printLinkList(LinkList head) {LinkList p = head->next;while (p != head) { //p != Lprintf("%c", p->data);p = p->next;}printf("\n");
}

三、循环单链表的基本操作完整代码(C语言)

#include <stdio.h>
#include <conio.h>//getche()
#include <cstdlib>//free()#define OK 1
#define ERROR 0typedef char ElemType;
typedef int Status;typedef struct LNode {ElemType data;struct LNode *next;
} LNode, *LinkList;//循环链表初始化
Status InitList(LinkList &head) {head = new LNode;//head->next=NULL;head->next = head;return OK;
}//功能菜单
Status choice() {printf("==================================\n");printf("         循环链表操作功能菜单        \n");printf("1、插入元素  2、查询表长  3、按位查找\n");printf("4、按值查找  5、删除元素  6、销毁链表\n");printf("7、清空链表  8、批量插入  9、链表元素\n");printf("10、头插法创建单链表11、尾插法创建单链表\n");printf("==================================\n");return 1;
}//插入
Status ListInsert(LinkList &head, int i, ElemType e) {LinkList p = head;int j = 0;while (p && (j < i - 1)) {p = p->next;j++;}if (!p || j > i - 1) {return ERROR;}LNode *s = new LNode;s->data = e;s->next = p->next;p->next = s;return OK;
}//求单链表长度
Status GetLinkListLength(LinkList head) {LinkList p = head->next;int length = 0;while (p != head) {   //p!=NULL          //单链表不为空表时length++;p = p->next;}return length;
}//销毁
Status DestoryLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L  p!=NULLq = p;p = p->next;delete q;}head->next = NULL;// printf("\n销毁成功\n");return OK;
}//清空
Status ClearLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L  p!=NULLq = p;p = p->next;delete q;}head->next = head; //链表为空return OK;
}//取值
Status GetLinkList(LinkList head, int i, ElemType &e) {LinkList p = head->next;int j = 1;while (p != head && j < i) {  //p != Lp = p->next;j++;}if (p == head) {//p==Lreturn ERROR;}e = p->data;return OK;
}//查找
int LocateLinkListElem(LinkList head, ElemType e) {LinkList p = head->next;int j = 1;while (p != head && (p->data != e)) {//p != L p!=NULLp = p->next;j++;}if (p == head) { //p==L  !p<=>p==NULLreturn 0;}return j;
}//删除
Status ListDelete(LinkList &head, int i, ElemType &e) {LinkList p = head;int j = 0;while (p->next != head && j < i - 1) {  //p != Lp = p->next;j++;}if (p->next == head) { //p==Lreturn ERROR;}LinkList q = p->next;e = q->data;p->next = q->next;delete q;return OK;
}//头插法创建循环链表
void CreateLinkList_H(LinkList &head, int n) {InitList(head);for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;p->next = head->next;head->next = p;}
}//尾插法创建循环链表
void CreateLinkList_R(LinkList &head, int n) {InitList(head);LinkList r = head;for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;//p->next=NULL   p->next=head//p->next = r->next;r->next = p;r = p;}r->next = head;                //尾结点next域指向头结点
}//输出链表元素
void printLinkList(LinkList head) {LinkList p = head->next;while (p != head) { //p != Lprintf("%c", p->data);p = p->next;}printf("\n");
}int main() {LinkList list;//初始化printf("单链表正在初始化....\n");int InitStatus = InitList(list);if (InitStatus == OK) {printf("单链表初始化成功!\n");} else {printf("单链表初始化失败!\n");}choice();    //调用功能菜单函数int temp = 1;  //通过改变temp的值来跳出while循环while (temp) {int flag;printf("请输入所需的功能编号:\n");scanf("%d", &flag);switch (flag) {//通过开关进行功能选择case 1: {//插入元素int insertIndex;ElemType inserElem;printf("请输入插入元素位置及插入元素(请在英文状态下输入例如:1,a): \n");scanf("%d,%c", &insertIndex, &inserElem);Status InsertS = ListInsert(list, insertIndex, inserElem);if (InsertS == OK) {printf("向循环链表%d个位置,插入元素为%c成功!\n\n", insertIndex, inserElem);} else {printf("向循环链表插入元素失败!\n\n");}}break;case 2: {//求单链表的长度int length = GetLinkListLength(list);printf("循环链表的长度为:%d。 \n\n", length);}break;case 3: {//取值Status GetIndex;printf("请输入需要查询的元素的位置:\n");scanf("%d", &GetIndex);ElemType GetElem;int GetStatus = GetLinkList(list, GetIndex, GetElem);if (GetStatus == OK) {printf("从循环链表中获取第%d位置元素成功,所获取到的元素为:%c。\n\n", GetIndex, GetElem);} else {printf("从循环链表中获取第%d位置元素失败!\n\n", GetIndex);}}break;case 4: {//查找ElemType LocateElem;printf("请输入想要查找元素:\n");getchar();    //用于接收回车scanf("%c", &LocateElem);Status LocateIndex = LocateLinkListElem(list, LocateElem);if (LocateIndex > 0) {printf("从循环链表中查找元素%c成功,它在循环链表中的位置为第%d个!\n\n", LocateElem, LocateIndex);} else {printf("从循环链表中查找元素%c失败!\n\n", LocateElem);}}break;case 5: {//删除Status DeleteIndex;printf("请输入想要删除元素的位置:\n");scanf("%d", &DeleteIndex);ElemType DeleteElem;ElemType DeleteStatus = ListDelete(list, DeleteIndex, DeleteElem);if (DeleteStatus == OK) {printf("删除循环链表第%d个位置的元素成功,删除的元素为:%c。\n\n", DeleteIndex, DeleteElem);} else {printf("删除循环链表第%d个位置的元素失败!\n\n", DeleteIndex);}}break;case 6: {//销毁Status DestoryStatus = DestoryLinkList(list);if (DestoryStatus == OK) {printf("循环链表销毁成功!\n\n");} else {printf("循环链表销毁失败!\n\n");}}break;case 7: {//清空Status ClearStatus = ClearLinkList(list);if (ClearStatus == OK) {printf("循环链表清空成功!\n\n");} else {printf("循环链表清空失败!\n\n");}}break;case 8: {//批量插入int on;printf("请输入想要插入的元素个数:\n");scanf("%d", &on);ElemType array[on];for (int i = 1; i <= on; i++) {getchar();printf("向循环链表第%d个位置插入元素为:", (i));scanf("%c", &array[i]);}for (int i = 1; i <= on; i++) {Status InsertStatus = ListInsert(list, i, array[i]);if (InsertStatus == OK) {printf("向循环链表第%d个位置插入元素%c成功!\n", i, array[i]);} else {printf("向循环链表第%d个位置插入元素%c失败!\n", i, array[i]);}}}break;case 9: {//输出链表元素//temp=0;//return 0;printf("现在链表的元素为:");printLinkList(list);}break;case 10: {//头插法创建单链表//getchar();LinkList L;printf("请输入五个字符:\n");CreateLinkList_H(L, 5);int length = GetLinkListLength(L);printf("\n循环链表的长度为:%d。 \n", length);printf("循环链表的元素为:");printLinkList(L);printf("\n");}break;case 11: {//尾插法创建单链表LinkList L;printf("请输入五个字符:\n");CreateLinkList_R(L, 5);int length = GetLinkListLength(L);printf("\n循环链表的长度为:%d。 \n", length);printf("循环链表的元素为:");printLinkList(L);printf("\n");}break;default:printf("输入错误,无此功能,请检查输入:\n\n");}}}

四、运行结果

 

 

 

 

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

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

相关文章

人工智能(AI)技术应用:解锁未来的无限可能

随着信息时代的来临&#xff0c;人工智能(AI)技术成为推动社会进步的重要力量。在医疗领域&#xff0c;人工智能技术已经开始发挥重要作用。通过大数据分析和机器学习&#xff0c;人工智能可以帮助医生更准确地诊断疾病、制定治疗方案&#xff0c;缩短治疗时间&#xff0c;提高…

Modbus协议学习第五篇之libmodbus库的编译

前言 本篇博客主要讲解在Windows下的libmodbus库的编译过程&#xff0c;供大家参考。 所需环境&#xff1a;Windows操作系统/ Visual Studio / Github 具体步骤 第一步&#xff1a;下载并解压libmodbus源码 首先我们进入libmodbus库的github地址&#xff1a;libmodbus&#x…

在Go中处理HTTP请求和响应

在Go语言中&#xff0c;处理HTTP请求和响应的关键在于对net/http包的理解和使用。这个包提供了强大的工具&#xff0c;使开发者能够轻松地构建Web应用程序。以下是一个简单的示例&#xff0c;展示了如何在Go中处理HTTP请求和响应。 首先&#xff0c;确保你已经安装了Go语言的开…

记一次NAS问题修复,挂载的硬盘名称发生变化导致文件上传失败,解决问题方案总结

我之前采用Cloudreve搭建了一个内网穿透的网盘管理&#xff0c;最近突发发现文件上传失败&#xff0c;且内容无法访问&#xff0c;这个问题纠结了我一个星期&#xff0c;最终发现是由于挂载的硬盘原来的目录是dve/sda1 不知道什么原因这个名称变成了sdc1 原因解释&#xff1a; …

图像分割实战-系列教程17:deeplabV3+ VOC分割实战5-------main.py

&#x1f341;&#x1f341;&#x1f341;图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 deeplab系列算法概述 deeplabV3 VOC分割实战1 deeplabV3 VOC分割实战2 deeplabV3 VOC分割实战3 dee…

智能算法 | Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数对比与秩和检验

智能算法 | Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数对比与秩和检验 目录 智能算法 | Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数对比与秩和检验预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数…

Flutter编译报错Connection timed out: connect

背景&#xff1a;用Android Studo 创建了Flutter项目&#xff0c;编译运行报错java.net.ConnectException: Connection timed out: connect 我自己的环境&#xff1a; windows11 Android Studio Flutter 截图如下&#xff1a; 将错误日志展开之后&#xff1a; Exception…

LLM面面观之LLM上下文扩展方案

1. 背景 本qiang~这段时间调研了LLM上下文扩展的问题&#xff0c;并且实打实的运行了几个开源的项目&#xff0c;所谓实践与理论相结合嘛&#xff01; 此文是本qiang~针对上下文扩展问题的总结&#xff0c;包括解决方案的整理概括&#xff0c;文中参考了多篇有意义的文章&…

【C++】类和对象(上篇)

文章目录 &#x1f6df;一、面向过程和面向对象初步认识&#x1f6df;二、类的引入&#x1f6df;三、类的定义&#x1f4dd;1、类的两种定义方式&#x1f4dd;2、成员变量命名规则的建议 &#x1f6df;四、类的访问限定符及封装&#x1f369;1、访问限定符&#x1f369;2、封装…

鼠害监测站设立的意义是什么

鼠害监测站对草原生态环境的影响主要体现在以下几个方面&#xff1a; 保护草原植被&#xff1a;鼠害监测站通过实时监测鼠害活动&#xff0c;及时采取控制措施&#xff0c;可以有效减少鼠类对草原植被的破坏&#xff0c;保护草原生态系统的稳定性。维持草原土壤健康&#xff1…

C++ 知识列表【图】

举例C的设计模式和智能指针 当谈到 C 的设计模式时&#xff0c;以下是一些常见的设计模式&#xff1a; 工厂模式&#xff08;Factory Pattern&#xff09;&#xff1a;用于创建对象的模式&#xff0c;隐藏了对象的具体实现细节&#xff0c;只暴露一个公共接口来创建对象。 单例…

Web04--Flex布局

1、flex布局 1.1 flex认识 1.2 flex组成 1.3 flex布局 1.3.1 主轴对齐方式 <!DOCTYPE html> <html lang"CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.…

解决Windows下Goland的Terminal设置为Git Bash失败

路径不要选错了&#xff1a; 如果还是不行&#xff1a; 把bash路径加进去试试 goland设置Terminal

uni-app小程序:文件下载打开文件方法苹果安卓都适用

api: const filetype e.substr(e.lastIndexOf(.)1)//获取文件地址的类型 console.log(文档,filetype) uni.downloadFile({url: e,//e是图片地址success(res) {console.log(res)if (res.statusCode 200) {console.log(下载成功,);var filePath encodeURI(res.tempFilePath);…

爬虫案例—抓取找歌词网站的按歌词找歌名数据

爬虫案例—抓取找歌词网站的按歌词找歌名数据 找个词网址&#xff1a;https://www.91ge.cn/lxyyplay/find/ 目标&#xff1a;抓取页面里的所有要查的歌词及歌名等信息&#xff0c;并存为txt文件 一共46页数据 网站截图如下&#xff1a; 抓取完整歌词数据&#xff0c;如下图…

DevOps系列文章之 GitLab CI/CD

CICD是什么? 由于目前公司使用的gitlab&#xff0c;大部分项目使用的CICD是gitlab的CICD&#xff0c;少部分用的是jenkins&#xff0c;使用了gitlab-ci一段时间后感觉还不错&#xff0c;因此总结一下 介绍gitlab的CICD之前&#xff0c;可以先了解CICD是什么 我们的开发模式…

司铭宇老师:房地产中介销售经理培训:如何激发房产中介销售人员的斗志与激情

房地产中介销售经理培训&#xff1a;如何激发房产中介销售人员的斗志与激情 在房产中介行业&#xff0c;销售人员的斗志与激情直接影响着业绩的高低。一个有动力的销售团队能够积极应对市场的变化&#xff0c;更好地服务客户&#xff0c;从而实现销售目标。本文将探讨如何通过有…

CGLIB动态代理(AOP原理)(面试重点)

推荐先看JDK 动态代理&#xff08;Spring AOP 的原理&#xff09;&#xff08;面试重点&#xff09; JDK 动态代理与 CGLIB 动态代理的区别 JDK 动态代理有⼀个最致命的问题是其只能代理实现了接⼝的类. 有些场景下,我们的业务代码是直接实现的,并没有接⼝定义.为了解决这个问…

【C++干货基地】namespace超越C语言的独特魅力(文末送书)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

HarmonyOS4.0系统性深入开发24启动DataAbility

DataAbility组件概述 DataAbility&#xff0c;即"使用Data模板的Ability"&#xff0c;主要用于对外部提供统一的数据访问抽象&#xff0c;不提供用户交互界面。DataAbility可由PageAbility、ServiceAbility或其他应用启动&#xff0c;即使用户切换到其他应用&#x…