循环链表 -- c语言实现
#pragma once
// 带头+双向+循环链表增删查改实现
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>typedef int LTDataType;typedef struct ListNode
{LTDataType data;struct ListNode* next;struct ListNode* prev;
}ListNode;//双链表申请一个新节点
ListNode* BuyListNode(LTDataType x);// 创建返回链表的头结点
ListNode* ListCreate();// 双向链表打印
void ListPrint(ListNode* pHead);// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x);// 双向链表尾删
void ListPopBack(ListNode* pHead);// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x);// 双向链表头删
void ListPopFront(ListNode* pHead);// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x);// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);// 双向链表销毁
void ListDestory(ListNode* pHead);//双链表申请一个新节点
ListNode* BuyListNode(LTDataType x)
{ListNode* node = (ListNode*)malloc(sizeof(ListNode));if (node == NULL){perror("BuyListNode::malloc");return NULL;}node->data = x;node->next = NULL;node->prev = NULL;return node;
}// 创建返回链表的头结点
ListNode* ListCreate()
{ListNode* head = BuyListNode(-1);head->next = head;head->prev = head;
}// 双向链表打印
void ListPrint(ListNode* pHead)
{assert(pHead);ListNode* cur = pHead->next;printf("head<=>");while (cur != pHead){printf("%d<=>", cur->data);cur = cur->next;}printf("\n");return;
}// 双向链表尾插
// void ListPushBack(ListNode* pHead, LTDataType x)
// {
// assert(pHead);
// ListNode* newnode = BuyListNode(x);
// ListNode* tail = pHead->prev;
// tail->next = newnode;
// newnode->prev = tail;
// newnode->next = pHead;
// pHead->prev = newnode;
// return;
// }
// 下面的写法更容易理解
void ListPushBack(ListNode* pHead, LTDataType x)
{assert(pHead);ListNode* newnode = BuyListNode(x);newnode->next = pHead;newnode->prev = pHead->prev;pHead->prev->next = newnode;pHead->prev = newnode;return;}// 双向链表尾删
void ListPopBack(ListNode* pHead)
{assert(pHead);ListNode* tail = pHead->prev;if (tail == pHead)return;tail->prev->next = pHead;pHead->prev = tail->prev;free(tail);tail = NULL;return;
}// 双向链表头插
// void ListPushFront(ListNode* pHead, LTDataType x)
// {
// assert(pHead);
// ListNode* newnode = BuyListNode(x);
// newnode->next = pHead->next;
// pHead->next->prev = newnode;
// pHead->next = newnode;
// newnode->prev = pHead;
// return;
// }void ListPushFront(ListNode* pHead, LTDataType x)
{assert(pHead);ListNode* newnode = BuyListNode(x);newnode->next = pHead->next;newnode->prev = pHead;pHead->next->prev = newnode;pHead->next = newnode;return;
}// 双向链表头删
void ListPopFront(ListNode* pHead)
{assert(pHead);ListNode* tmp = pHead->next;if (tmp == pHead)return;tmp->next->prev = pHead;pHead->next = tmp->next;free(tmp);tmp = NULL;
}// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x)
{assert(pHead);ListNode* cur = pHead;while (cur->data != x){cur = cur->next;if (cur == pHead)return NULL;}return cur;
}// 双向链表在pos的前面进行插入
// void ListInsert(ListNode* pos, LTDataType x)
// {
// assert(pos);
// ListNode* newnode = BuyListNode(x);
// pos->prev->next = newnode;
// newnode->prev = pos->prev;
// pos->prev = newnode;
// newnode->next = pos;
// return;
// }
// 下面这个更好理解,且避免了pos为头节点时若头节点的 next 为 NULL 时的错误
void ListInsert(ListNode* pos, LTDataType x)
{assert(pos);ListNode* newnode = BuyListNode(x);newnode->next = pos;newnode->prev = pos->prev;pos->prev->next = newnode;pos->prev = newnode;return;
}// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;return;
}// 双向链表销毁
void ListDestory(ListNode* pHead)
{assert(pHead);ListNode* cur = pHead->next;while (cur != pHead){ListNode* tmp = cur->next;free(cur);cur = tmp;}free(pHead);return;
}int main() {// 创建一个双向循环链表,头节点headListNode* myList = ListCreate();// 尾插元素ListPushBack(myList, 1);ListPushBack(myList, 2);ListPushBack(myList, 3);// 头插元素ListPushFront(myList, 0);// 打印链表ListPrint(myList); // 应该输出:head<=>0<=>1<=>2<=>3<=>// 查找元素ListNode* foundNode = ListFind(myList, 2);if (foundNode != NULL) {printf("找到的节点的data: %d\n", foundNode->data); // 应该输出:Found node with value: 2} else {printf("没有找到\n");}// 在指定位置前插入元素ListInsert(foundNode, 10);// 打印链表ListPrint(myList); // 应该输出:head<=>0<=>1<=>10<=>2<=>3<=>// 删除指定位置的元素ListErase(foundNode);// 打印链表ListPrint(myList); // 应该输出:head<=>0<=>1<=>10<=>3<=>// 头删元素ListPopFront(myList);// 尾删元素ListPopBack(myList);// 打印链表ListPrint(myList); // 应该输出:head<=>1<=>2<=>// 打印 head 的 prev 的 dataprintf("head->prev->data: %d", myList->prev->data);// 销毁链表ListDestory(myList);return 0;
}
运行结果:

相关文章:
循环链表 -- c语言实现
#pragma once // 带头双向循环链表增删查改实现 #include<stdlib.h> #include<stdio.h> #include<assert.h>typedef int LTDataType;typedef struct ListNode {LTDataType data;struct ListNode* next;struct ListNode* prev; }ListNode;//双链表申请一个新节…...
如何使git提交的时候忽略一些特殊文件?
认识.gitignore文件 在生成远程仓库的时候我们会看到这样一个选项: 这个.gitignore文件有啥用呢? .gotignore文件是Git版本控制系统中的一个特殊文件。用来指定哪些文件或者目录不被Git追踪或者提交到版本库中。也就意味着,如果我们有一些文…...
如何保证Redis双写一致性?
目录 数据不一致问题 数据库和缓存不一致解决方案 1. 先更新缓存,再更新数据 该方案数据不一致的原因 2. 先更新数据库,再更新缓存 3. 先删除缓存,再更新数据库 延时双删 4. 先更新数据库,再删除缓存 该方案数据不一致的…...
HarmonyOS实战开发-如何实现查询当前城市实时天气功能
先来看一下效果 本项目界面搭建基于ArkUI中TS扩展的声明式开发范式, 数据接口是和风(天气预报), 使用ArkUI自带的网络请求调用接口。 我想要实现的一个功能是,查询当前城市的实时天气, 目前已实现的功能…...
(三)JSP教程——JSP动作标签
JSP动作标签 用户可以使用JSP动作标签向当前输出流输出数据,进行页面定向,也可以通过动作标签使用、修改和创建对象。 <jsp:include>标签 <jsp:include>标签将同一个Web应用中静态或动态资源包含到当前页面中。资源可以是HTML、JSP页面和文…...
centos7安装真的Redmine-5.1.2+ruby-3.0.0
下载redmine-5.1.2.tar.gz,上传到/usr/local/目录下 cd /usr/local/ tar -zxf redmine-5.1.2.tar.gz cd redmine-5.1.2 cp config/database.yml.example config/database.yml 配置数据连接 #编辑配置文件 vi config/database.yml #修改后的内容如下 product…...
方法的重写
方法的重写 概念:子类继承父类之后,就拥有了符合权限的父类的属性和方法,但是当父类的方法不符合子类的要求的时候,子类也可以重新的书写自己想要的方法。所以,方法的重写,即子类继承父类的方法后…...
Terraform局部值
Terraform输入变量用于从外部传递值到Terraform模块内部进行使用,如果把Terraform代码看作是一个函数的话,Terraform输入变量就是函数的输入参数。 Terraform局部值则用于在Terraform模块内部定义反复使用的常量值或表达式,如果把Terraform代…...
vue+element-ui实现横向长箭头,横向线上下可自定义文字(使用after伪元素实现箭头)
项目场景: 需要实现一个长箭头,横向线上下可自定义文字 代码描述 <div><span class"data-model">{{ //上方文字}}</span><el-divider class"q"> </el-divider>//分隔线<span class"data-mod…...
性能监控之prometheus+grafana搭建
前言 Prometheus和Grafana是两个流行的开源工具,用于监控和可视化系统和应用程序的性能指标。它们通常一起使用,提供了强大的监控和数据可视化功能。 Prometheus Prometheus是一种开源的系统监控和警报工具包。它最初由SoundCloud开发,并于…...
25-ESP32-S3 内置的真随机数发生器(RNG)
ESP32-S3 内置的真随机数发生器(RNG)😎 引言 📚 在许多应用中,随机数发生器(RNG)是必不可少的。无论是在密码学🔒、游戏🎮、模拟🧪或其他领域,随…...
万兆以太网MAC设计(12)万兆UDP协议栈上板与主机网卡通信
文章目录 一、设置IP以及MAC二、上板效果2.1、板卡与主机数据回环测试2.2、板卡满带宽发送数据 一、设置IP以及MAC 顶层模块设置源MAC地址 module XC7Z100_Top#(parameter P_SRC_MAC 48h01_02_03_04_05_06,parameter P_DST_MAC 48hff_ff_ff_ff_ff_ff )(input …...
2024年4月17日华为春招实习试题【三题】-题目+题解+在线评测,2024.4.17,华为机试
2024年4月17日华为春招实习试题【三题】-题目题解在线评测 🔮题目一描述:扑克牌消消乐输入描述输出描述样例一样例二Limitation解题思路一:模拟,遇到连续3张相同牌号的卡牌,直接删除解题思路二:栈解题思路三…...
展开说说:Android线程池解析
何谓线程池?本人理解是存放和管理线程的一个容器。 线程池存在的意义是什么? 第一:前面博客提到过创建和销毁线程的操作本身是有性能开销的,如果把使用的线程对象存起来下次用的时候直接取出来用就省去了一次创建和销毁的成本&a…...
Selenium自动化测试面试题全家桶
🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 …...
Docker 容器日志占用空间过大解决办法
1、vi /etc/docker/daemon.json {"log-driver":"json-file","log-opts": {"max-size":"200m", "max-file":"1"} } 2、重新加载守护进程配置文件 systemctl daemon-reload 3、重启docker systemctl…...
update_min_vruntime()流程图
linux kernel scheduler cfs的update_min_vruntime() 看起来还挺绕的。含义其实也简单,总一句话,将 cfs_rq->min_vruntime 设置为: max( cfs_rq->vruntime, min(leftmost_se->vruntime, cfs_rq->curr->vruntime) )。 画个流…...
十进制转任意进制(以及任意进制来回转换<了解>)
十进制转任意进制: #include <iostream> #include <vector> #include <string> using namespace std; // 将十进制数转换为P进制形式的字符串 string toBase(int num, int base) {string result ""; // 初始化结果字符串为空wh…...
postcss-px-to-viewport 从入坑到放弃 (nuxt3搭建响应式官网解决方案 )
前沿 什么是 postcss-px-to-viewport 将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的 PostCSS 插件。 为什么使用 postcss-px-to-viewport 在pc端盛行的时代 ,如果你不想去适配更多的pc端代码,可以采用它。 由于nuxt3本身已带postcss,所…...
C语言从入门到入门
一、引言 C语言是一种通用的、过程式的计算机编程语言,支持结构化编程、词汇变量作用域和递归等功能,其设计提供了低级别的存取权限,并且要求程序员管理所有的内存细节。C语言具有高效、灵活和可移植性等特点,因此被广泛应用于系统编程、嵌入式系统开发、游戏开发等领域。 …...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
