数据结构与算法学习笔记五---循环链表的表示和实现(C语言)

目录

前言

1.循环链表的表示和实现

1.初始化

2. 销毁

3. 清空

4. 表空判断

5. 表长

6. 获取循环链表中的元素

7. 直接前驱

8. 直接后继

9. 插入

10. 删除

11. 遍历

12. 测试代码 


前言

    这篇博客主要介绍C语言中循环链表的表示和实现。

1.循环链表的表示和实现

        指针是C语言中的一种重要概念,它存储了一个变量的内存地址。通过指针,可以直接访问内存中的数据,实现对数据的直接操作。

1.初始化

        指针的声明告诉编译器变量将存储一个地址。在声明指针时,需要指定指针所指向变量的类型。

        例如在下面的例子中我们声明了一个指向整数的指针变量。

int * ptr;

2. 销毁

// 循环链表销毁
void destroyCircularLinkedList(CircularLinkedList *circularLinkedList) {if (*circularLinkedList) {CircularLinkedList current = (*circularLinkedList)->next;while (current != *circularLinkedList) {CircularLinkedList temp = current;current = current->next;free(temp);}free(*circularLinkedList);*circularLinkedList = NULL;}
}

3. 清空

// 循环链表清空
void clearCircularLinkedList(CircularLinkedList *circularLinkedList) {if (!circularLinkedList) {return; // 链表为空,无需清空}CircularLinkedList current = (*circularLinkedList)->next; // 从第一个节点开始while (current != *circularLinkedList) { // 遍历至头节点CircularLinkedList temp = current; // 暂存当前节点current = current->next; // 移动到下一个节点free(temp); // 释放当前节点内存}(*circularLinkedList)->next = *circularLinkedList; // 头节点的 next 指针指向自身,链表置为空链表
}

4. 表空判断

// 循环链表是否为空
Status isCircularLinkedListEmpty(CircularLinkedList *circularLinkedList) {return (*circularLinkedList)->next == *circularLinkedList ? 1 : 0; // 头节点的 next 指针指向自身表示链表为空
}

5. 表长

// 循环链表表长
int getCircularLinkedListLength(CircularLinkedList *circularLinkedList) {int length = 0;CircularNode *p = (*circularLinkedList)->next; // 从第一个节点开始计数while (p != *circularLinkedList) { // 当指针指向头节点时结束循环++length;p = p->next;}return length;
}

6. 获取循环链表中的元素

// 获取循环链表中的元素
Status getCircularLinkedListElement(CircularLinkedList *circularLinkedList, int position, int *element) {if (position < 1 || position > getCircularLinkedListLength(circularLinkedList)) { // 非法位置return 0;}CircularNode *p = (*circularLinkedList)->next; // 从第一个节点开始遍历int index = 1;while (index < position) { // 定位到指定位置p = p->next;index++;}*element = p->data; // 将节点的数据域值赋给 elementreturn 1;
}

7. 直接前驱

// 获取循环链表中的第一个与 element 相同的元素的直接前驱
Status priorCircularLinkedListElement(CircularLinkedList *circularLinkedList, int element, int *priorElement) {if (isCircularLinkedListEmpty(circularLinkedList)) { // 空链表return 0;}CircularNode *p = (*circularLinkedList)->next;CircularNode *pre = *circularLinkedList; // 前驱节点do {if (p->data == element) { // 找到要查找的节点*priorElement = pre->data;return 1;}pre = p;p = p->next;} while (p != (*circularLinkedList)->next); // 循环直到回到起始节点return 0; // 未找到相同元素
}

8. 直接后继

// 获取循环链表中的第一个与 element 相同的元素的后继节点
Status nextCircularLinkedListElement(CircularLinkedList *circularLinkedList, int element, int *nextElement) {if (isCircularLinkedListEmpty(circularLinkedList)) { // 空链表return 0;}CircularNode *p = (*circularLinkedList)->next;do {if (p->data == element) { // 找到要查找的节点*nextElement = p->next->data;return 1;}p = p->next;} while (p != (*circularLinkedList)->next); // 循环直到回到起始节点return 0; // 未找到相同元素
}

9. 插入

// 循环链表插入
Status insertCircularLinkedList(CircularLinkedList *circularLinkedList, int i, int element) {if (i < 1) { // 插入位置非法return 0;}CircularNode *newNode = (CircularNode *)malloc(sizeof(CircularNode)); // 新节点if (!newNode) { // 内存分配失败return 0;}newNode->data = element;if (i == 1) { // 插入到表头if (*circularLinkedList == NULL) { // 空链表newNode->next = newNode; // 自己指向自己*circularLinkedList = newNode;} else {CircularNode *last = *circularLinkedList;while (last->next != *circularLinkedList) { // 找到最后一个节点last = last->next;}newNode->next = *circularLinkedList; // 新节点指向表头last->next = newNode; // 最后一个节点指向新节点*circularLinkedList = newNode; // 更新表头指针}} else { // 插入到非表头位置CircularNode *p = *circularLinkedList;int j = 1;while (p->next != *circularLinkedList && j < i - 1) { // 找到插入位置的前一个节点p = p->next;++j;}if (j < i - 1) { // 插入位置超出链表长度free(newNode);return 0;}newNode->next = p->next; // 新节点指向原来位置节点p->next = newNode; // 前一个节点指向新节点}return 1;
}

10. 删除

// 循环链表删除
Status deleteCircularLinkedList(CircularLinkedList *circularLinkedList, int position, ElemType *deletedElement) {if (position < 1 || *circularLinkedList == NULL) { // 删除位置非法或链表为空return 0;}if (position == 1) { // 删除表头节点CircularNode *temp = *circularLinkedList;*deletedElement = temp->data; // 存储被删除节点的数据if ((*circularLinkedList)->next == *circularLinkedList) { // 链表只有一个节点free(temp);*circularLinkedList = NULL;} else {CircularNode *last = *circularLinkedList;while (last->next != *circularLinkedList) { // 找到最后一个节点last = last->next;}last->next = (*circularLinkedList)->next; // 最后一个节点指向第二个节点*circularLinkedList = (*circularLinkedList)->next; // 更新表头指针free(temp); // 释放被删除节点的内存}} else { // 删除非表头节点CircularNode *p = *circularLinkedList;int j = 1;while (p->next != *circularLinkedList && j < position - 1) { // 找到要删除节点的前一个节点p = p->next;++j;}if (j < position - 1 || p->next == *circularLinkedList) { // 删除位置超出范围return 0;}CircularNode *temp = p->next; // 要删除的节点*deletedElement = temp->data; // 存储被删除节点的数据p->next = temp->next; // 前一个节点指向后一个节点free(temp); // 释放被删除节点的内存}return 1;
}

11. 遍历

// 遍历循环链表
void traverseCircularLinkedList(CircularLinkedList *circularLinkedList) {if (*circularLinkedList == NULL) { // 空链表return;}CircularNode *p = *circularLinkedList;do {printf("%d\t", p->data); // 输出当前节点的数据p = p->next; // 移动到下一个节点} while (p != *circularLinkedList); // 循环直到回到起始节点printf("\n");
}

12. 测试代码 

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

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

相关文章

SpringCloud------Eureka,Ribbon,Nacos

认识微服务 微服务技术栈 微服务概念 微服务结构 微服务技术对比 企业需求 SpringCloud 认识Springcloud 服务拆分及远程调用 每个服务只能查询自己数据库中的表&#xff0c;导致其他服务如果想使用别人的表数据&#xff0c;这就需要进行远程调用&#xff0c;这里使用RestTem…

杨校老师项目之基于51单片机的汽车智能照明系统【嵌入式】

获取全套资料&#xff1a; 有偿获取&#xff1a;mryang511688 技术&#xff1a;C语言、单片机等 摘要&#xff1a; 科技的发展&#xff0c;人们对汽车的安全性也提出了更高要求。照明系统作为汽车组成部分之一&#xff0c;承担着重要职能&#xff0c;传统汽车智能照明系统已无法…

Spring Boot集成@Async快速入门Demo

1.什么是Async&#xff1f; 当我们在使用SpringBoot进行开发的时候&#xff0c;可能会遇到一些执行异步任务的场景&#xff0c;如果每次执行这些异步任务都去新建一个异步线程来执行的话&#xff0c;那代码就太冗余了。幸好SpringBoot给我们提供了Async的注解&#xff0c;让我…

【云计算小知识】云管理的作用是什么?

云计算已经成为推动企业数字化转型&#xff0c;提升运营效率的重要力量。而在这个过程中&#xff0c;云管理作为确保云计算环境稳定、高效运行的关键环节&#xff0c;其作用愈发凸显。今天我们小编就给大家详细介绍一下云管理的作用是什么&#xff1f; 云管理的作用是什么&…

小程序的小组件

进度的组件 文字换行过滤 以及 排序 简单易懂 只为了记录工作 <template><div><ProgressBar :progress"progress" /><button click"increaseProgress">增加进度</button><view class"goods-name">12…

【408精华知识】提高外部排序速度的三种方式

文章目录 一、败者树二、置换-选择排序三、最佳归并树 一、败者树 还没写完… 二、置换-选择排序 三、最佳归并树 写在后面 这个专栏主要是我在学习408真题的过程中总结的一些笔记&#xff0c;因为我学的也很一般&#xff0c;如果有错误和不足之处&#xff0c;还望大家在评…

Wikimedia To Opensearch

概览 Wikimedia ⇒ Kafka ⇒ OpensearchJava Library&#xff1a;OKhttp3和OkHttp EventSource&#xff1b;生产者&#xff1a;Wikimedia&#xff1a;WikimediaChangeHandler和WikimediaChangeProducer&#xff1b;消费者&#xff1a;Opensearch&#xff1a;OpenSearchConsume…

AI智能体|我把Kimi接入了个人微信

大家好&#xff0c;我是无界生长。 最近加入AI学习交流群的小伙伴越来越多&#xff0c;我打算在微信群接入一个聊天机器人&#xff0c;让它协助管理微信群&#xff0c;同时也帮忙给群友解答一些问题。普通的群聊机器人肯定是不能满足需求的&#xff0c;得上AI大模型&#xff0c…

Kylin V10SP1桌面版下GBase 8s java udr异常处理

同样的GBase 8s数据库版本&#xff0c;自定义的java udr在Kylin V10SP1 服务器版&#xff08;aarch64架构&#xff09;下创建、运行正常&#xff0c;而在Kylin V10SP1 桌面版&#xff08;aarch64架构&#xff09;下时创建正常但运行UDR异常&#xff0c;报错如下&#xff1a; (…

【JVM类加载机制】深度剖析JVM类加载机制

深度剖析JVM类加载机制 前言类加载运行全过程loadClass的类加载过程 类加载器和双亲委派机制类加载器的类型类加载器的初始化过程双亲委派机制为什么要设置双亲委派机制&#xff1f;全盘负责委托机制自定义类加载器实例打破双亲委派机制Tomcat打破双亲委派机制Tomcat自定义加载…

问题解决记录 | kettle中出现中文乱码

spoon.bat的启动文件中进行修改 if "%PENTAHO_DI_JAVA_OPTIONS%""" set PENTAHO_DI_JAVA_OPTIONS"-Xms1024m" "-Xmx2048m" "-Dfile.encodingUTF-8"

spark结课之小小tip

scala常用方法总结&#xff1a; 1.map()方法&#xff1a;用于对集合中的每个元素应用一个函数&#xff0c;并将结果收集到一个新的集合中。 基本结构&#xff1a; def map[B](f: (A) > B): List[B] 实例&#xff1a; val numbers List(1, 2, 3, 4, 5) val doubledNumber…

废品回收小程序,推动回收行业数字化发展

在垃圾分类、资源回收利用的时代背景下&#xff0c;废品回收行业迅速成长&#xff0c;市场规模逐渐扩大&#xff01; 随着“互联网”应用的普及&#xff0c;废品回收行业也进入到了数字化回收领域&#xff0c;各大回收行业开始专注于发展智能回收。此外&#xff0c;线上废品回…

‘vue-cli-service‘ is not recognized as an internal or external command解决方案

vue-cli-service is not recognized as an internal or external command, operable program or batch file.解决方案 先进行 &#xff1a; npm install -g vue/cli 命令安装vue cli 是必须的。 如果 npm run build 还是报错 遇到同样的提示&#xff1a; 这时候先安装依赖 np…

leetcode56--合并区间

题目描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;interv…

智慧管家物业管理系统(小组项目)

目录 前言 一、项目介绍 1、目的和背景 2、项目主要内容 3、技术介绍 二、功能模块 1、重要文件结构 2、功能实现&#xff08;部分个人负责模块功能&#xff09; 2.1 展示房源信息页面 2.2 房屋详情页面 2.3 房源信息管理 三、功能模块页面 1、前台模块 2、后台…

【讲解下iCloud如何高效利用】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【C语言/数据结构】栈:从概念到两种存储结构的实现

目录 一、栈的概念 二、栈的两种实现方式 1.顺序表实现栈 2.链表实现栈 三、栈的顺序存储结构及其实现 1.栈的声明 2.栈的初始化 3.栈的销毁 4.栈的压栈 5.栈的弹栈 6.栈的判空 7.返回栈顶元素 8.返回栈的长度 四、栈的链式存储结构及其实现 1.栈的声明 2.栈的…

推荐非常方便的初始配置nginx的开源工具

官网 https://www.digitalocean.com/community/tools/nginx?global.app.langzhCN直接复制base64字符串在 /etc/nginx 目录执行&#xff0c;会自动生成配置文件&#xff0c;最后执行 使用tar解压新的压缩配置 tar -xzvf nginxconfig.io-xxx.com.tar.gz | xargs chmod 0644在…

用Transformers实现简单的大模型文本生成

根据输入的prompt&#xff0c;生成一段指定长度的文字。Llama跑起来太慢了&#xff0c;这里用GPT-2作为列子。 from transformers import GPT2LMHeadModel, GPT2Tokenizer import torchtokenizer GPT2Tokenizer.from_pretrained("gpt2") model GPT2LMHeadModel.fr…