链表的实现(c语言)
链表分为单链表、双链表和循环链表,这些理论知识在笔记中自然写了,这里我只写出其中的实现:
单链表的实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef struct Book {char bookname[20];char author[10];
}Book;typedef struct Node {Book book;struct Node *next;
}Node,*LinkList;//初始化链表
void initChainedTable(Node **L){ //ok*L=(LinkList)malloc(sizeof(Node));(*L)->next=NULL;
}
//尾结点插入
Node* putNodeByTail(Book book,Node *r){ //okNode *node=(Node*)malloc(sizeof(Node));node->book= book;node->next=NULL;r->next=node;return node;
}
//首节点插入
void putNodeByHead(Book book,LinkList L){ //okNode *node=(Node*)malloc(sizeof(Node));node->book=book;node->next=L->next;L->next=node;
}
//删除其中一个结点
void deleteNode(int i,LinkList L){ //okNode *node=L->next;int counter=1;if (i == 1) {if (node != NULL) {L->next = node->next;free(node);} else {printf("List is empty, cannot delete.\n");}return;}while(node&&counter<(i-1)){node=node->next;++counter;}if(!node||i<=0){printf("index is out of bound \n");}else{Node* delnode = node->next;if (delnode) {node->next = delnode->next;free(delnode);} else {printf("Node at index %d does not exist\n", i);}}}
//向链表中插入元素
void insertNode(Book book,int i,LinkList L){ //okNode *newnode=(Node*)malloc(sizeof(Node));Node *node=L->next;newnode->book=book;int count=1;while(node&&count<(i-1)){node=node->next;++count;}if(!node||i<=0){printf("index is out of bound\n");}else{newnode->next=node->next;node->next=newnode; }}
//判断链表是否为空
int isEmpty(LinkList L){ //okreturn L->next==NULL?1:0;
} //获取第i个结点
Node* getNode(int i,LinkList L){ //okNode* node=L->next;int count=1;while(node&&count<i){node=node->next;++count;}if(node&&i>0) return node;printf("index is out of bound\n");
}
//通过值获取到它的位置
int getIndex(Book book,LinkList L){ //okNode* node=L->next;int count=1;while(node&&strcmp(node->book.author,book.author)&&strcmp(node->book.bookname,book.bookname)){node=node->next;++count;}if(node) return -1;return count;
}
//打印链表中的数据
void printNodeData(LinkList L){ //okNode *node=L->next;while(node){printf("bookname:%s;author:%s\n",node->book.bookname,node->book.author);node=node->next;}if(!node) printf("你所给的是个空链表!\n");
}
//释放一个链表
void freeChainedTable(LinkList L){ Node *p=L->next;Node *q;while(p){ q=p->next;free(p);p=q; }printf("清除完成!\n");L->next=NULL;
}int main(){LinkList L;initChainedTable(&L);Book book1={"java","zhangyu"};Book book2={"php","zhang"};Book book3={"c#","nanchengyu"};putNodeByHead(book1,L);putNodeByHead(book2,L);putNodeByHead(book3,L);Book book4={"java","zhang"};freeChainedTable(L);printNodeData(L);system("pause");return 0;
}
双链表的实现
#include <stdio.h>
#include <stdlib.h>//这个源文件描述的是不循环双向链表typedef struct Book {char bookname[20];char author[10];
}Book;
typedef struct doLinkList{Book book;struct doLinkList *prior,*next;struct doLinkList *ele;
}Node,*LinkList;
//初始化链表
void initDoLinkList(LinkList *L){*L=(LinkList)malloc(sizeof(Node));(*L)->prior=NULL;(*L)->next=NULL;(*L)->ele=*L;
}
//向链表添加结点
void putNode(Book book,Node *listNode){Node *node=(Node*)malloc(sizeof(Node));node->book=book;listNode->ele->next=node;node->prior=listNode->ele;node->next=NULL;listNode->ele=node;
}
//打印结点数据
void printNodeData(LinkList list){if(!list->next){printf("你所给的是个空链表!\n"); return; } Node *node=list->next;while(node){printf("bookname:%s;author:%s\n",node->book.bookname,node->book.author);node=node->next;}
}
//查找链表数据
Node* getNode(int i,LinkList list){Node *node=list->next;int counter=1;while(node&&counter!=i&&i>0){node=node->next;++counter;}if(i<0||i>counter){printf("索引超出范围!\n");return NULL;}return node;
}//删除链表结点
void delNode(int i,LinkList list){Node *p;if(!(p=getNode(i,list))){printf("并没有找到该节点!\n");}else if(p->next){p->prior->next=p->next;p->next->prior=p->prior;}else{p->prior->next=NULL;}free(p);} //向双向节点中插入结点(末尾节点不可以插入)
void insertNode(int i,Book book,LinkList list){Node *p;Node *node=(Node*)malloc(sizeof(Node));node->book=book;if(p=getNode(i,list)){p->prior->next=node;node->prior=p->prior;node->next=p;p->prior=node;}else {printf("插入失败!\n");}
} int main(){LinkList L;initDoLinkList(&L);Book book1={"java","zhangyu"};Book book2={"php","zhang"};Book book3={"c#","nan"};putNode(book1,L);putNode(book2,L);
// putNode(book3,L);insertNode(2,book3,L);printNodeData(L);system("pause");return 0;
}
循环链表的实现
#include <stdio.h>
#include <stdlib.h>//这个源代码设计的是循环链表,包括设计的尾指针,两个循环链表的组合,但是链表的其他操作我们在这就不去写了
// 设计这个尾指针的目的是在对表的首尾部分进行操作的时候可以降低时间复杂度
typedef struct Book {char bookname[20];char author[10];
}Book;typedef struct Node{Book book;struct Node *next;
}Node;typedef struct LoopLinkList{Node *headNode;Node *tailNode;
} *LoopList;
//初始化循环列表
void initLoopLinkList(LoopList *L){ //okNode *headNode=(Node*)malloc(sizeof(Node));*L=(LoopList)malloc(sizeof(LoopList));(*L)->headNode=headNode;(*L)->tailNode=headNode;
}
//向循环链表中添加结点
void putNode(Book book,LoopList L){ //okNode *node=(Node*)malloc(sizeof(Node));node->book=book;L->tailNode->next=node;L->tailNode=node;node->next=L->headNode;
}//将第二个循环链表添加到第一个循环链表后
LoopList connectTable(LoopList L1,LoopList L2){ //0kL1->tailNode->next=L2->headNode->next;free(L2->headNode);L2->tailNode->next=L1->headNode;L1->tailNode=L2->tailNode;return L1;
}//打印链表中的数据
void printNodeData(LoopList L){ //okNode *node=L->headNode->next;while(node!=L->headNode){printf("bookname:%s;author:%s\n",node->book.bookname,node->book.author);node=node->next;}if(!node) printf("你所给的是个空链表!\n");
}
//获取循环列表的长度
int getSize(LoopList L){ //okNode *node=L->headNode->next;int counter=0;while(L->headNode!=L->tailNode&&node!=L->headNode){node=node->next;++counter;}return counter;
}int main(){LoopList L;initLoopLinkList(&L);Book book1={"java","zhangyu"};Book book2={"php","zhang"};Book book3={"c#","nan"};putNode(book1,L);putNode(book2,L);putNode(book3,L);printf("表1:\n");printNodeData(L);LoopList L2;initLoopLinkList(&L2);Book book4={"jaa","hangyu"};Book book5={"ph","zhng"};Book book6={"c","an"};putNode(book4,L2);putNode(book5,L2);putNode(book6,L2);printf("表2:\n");printNodeData(L2);LoopList list=connectTable(L,L2);printf("连接后的表:\n");printNodeData(list);system("pause");return 0;
}
补充:能不能实现循环双链表?这样循环有意义吗或者说这种数据结构有其特点和优势吗?有的话可以设计一下
相关文章:
链表的实现(c语言)
链表分为单链表、双链表和循环链表,这些理论知识在笔记中自然写了,这里我只写出其中的实现: 单链表的实现 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Book {char bookname[20];char a…...
【Redis】渐进式遍历
scan命令渐进式遍历 Redis使⽤scan命令进⾏渐进式遍历键,进⽽解决直接使⽤keys获取键时可能出现的阻塞问题。每次scan命令的时间复杂度是O(1),但是要完整地完成所有键的遍历,需要执⾏多次scan。 SCAN 以渐进式的⽅式进⾏键的遍历。 SCAN…...
uni-app开发微信小程序的报错[渲染层错误]排查及解决
一、报错信息 [渲染层错误] Framework nner error (expect FLOW INITIALCREATION end but get FLOW CREATE-NODE) 二、原因分析及解决方案 第一种 原因:基础库版本的原因导致的。 解决: 1.修改调试基础库版本 2.详情—>本地设置—>调试基础库…...
三、C语言常用运算符
1、算术运算符 符号说明加号-减号*乘号/除号%取余符号,相除以后余数是几自增运算符,整数值增加 1--自减运算符,整数值减少1 2、关系运算符 符号说明检查两个操作数的值是否相等,如果相等则条件为真。!检查两个操作数的值是否相…...
ubuntu联网图标消失
sudo service NetworkManager stopsudo rm /var/lib/NetworkManager/NetworkManager.statesudo service NetworkManager start执行 sudo rm /var/lib/NetworkManager/NetworkManager.state 命令将删除位于 /var/lib/NetworkManager 目录下的 NetworkManager.state 文件。...
中华人民共和国网络安全法
中华人民共和国网络安全法 《中华人民共和国网络安全法》已由中华人民共和国第十二届全国人民代表大会常务委员会第二十四次会议于2016年11月7日通过,现予公布,自2017年6月1日起施行。2022年9月12日,国家互联网信息办公室发布关于公开征求《…...
Java并发面试题:(二)线程池参数和使用
线程池参数 线程池工作过程 当提交一个新任务到线程池时,具体的执行流程如下: 当我们提交任务,线程池会根据corePoolSize大小创建若干任务数量线程执行任务 当任务的数量超过corePoolSize数量,后续的任务将会进入阻塞队列阻塞排…...
Python机器学习零基础理解AffinityPropagation亲和力传播聚类
如何解决社交媒体上的好友推荐问题? 想象一下,一个社交媒体平台希望提供更加精准的好友推荐功能,让用户能更容易地找到可能成为好友的人。这个问题看似简单,但当面对数百万甚至数千万的用户时,手动进行好友推荐就变得几乎不可能。 解决这个问题的一个方案就是使用机器学…...
Open3D 进阶(12)PCA拟合空间直线
目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 见:Open3D 最小二乘拟合空间直线(方法一) 二、代码实现 import numpy as np import open3d as o...
4种实现JS深拷贝的方法
浅拷贝与深拷贝 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的是内存地址 。 如果不进行深拷贝,其中一个对象改变了对象的值&am…...
六、RocketMQ发送事务消息
事务消息介绍 在一些对数据一致性有强需求的场景,可以用 Apache RocketMQ 事务消息来解决,从而保证上下游数据的一致性。 以电商交易场景为例,用户支付订单这一核心操作的同时会涉及到下游物流发货、积分变更、购物车状态清空等多个子系统的…...
Node.js初体验
Node.js简介 node.js的运行环境 1.V8引擎对js代码进行解析与执行 2.内置API:fs、path、http...等,提供了一些能力,能够使得js调用这些API去做一些后端的事情 流程:我们在node.js的运行环境中编写待执行的JavaScript代码&#…...
激活函数理解
激活函数(Activation Function)是神经网络中的一种数学函数,它的作用是为神经元(或人工神经元)引入非线性特性,从而使神经网络能够学习和表示更复杂的函数。激活函数通常位于神经元的输出端,接收…...
【docker - 安装】windows 10 专业版 安装docker,以及 WSL kernel version too low 解决方案
一、开启 Hyper-V 二、下载 docker 三、安装 docker 四、问题 Stage 1:打开 powershell,并执行 Stage 2:下载Linux内核更新包,并安装 Stage 3:将 WSL 2 设置为默认版本 Stage 4:安装所选的 Linux 分…...
洛谷P1601
题目见:P1601 AB Problem(高精) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 1. 问题分析 加法计算问题应该和在界面输出“Hello,world!”是一个难度级别,但是问题在于受限于原始数据类型的限制,无法进行大数据的精…...
Elasticsearch:使用 LangChain 对话链和 OpenAI 的聊天机器人
在此笔记本中,我们将构建一个聊天机器人,它可以回答有关自定义数据的问题,例如雇主的政策。 聊天机器人使用 LangChain 的 ConversationalRetrievalChain,具有以下功能: 用自然语言回答问题在 Elasticsearch 中运行混…...
铜死亡+机器学习+WGCNA+分型生信思路
今天给同学们分享一篇单基因泛癌免疫实验生信文章“IGF2BP3 overexpression predicts poor prognosis and correlates with immune infiltration in bladder cancer”,这篇文章于2023年2月3日发表在BMC Cancer期刊上,影响因子为3.8。 膀胱癌是全球最常见…...
GB28181平台简介
产品简介 LiveMedia视频中间件是支持部署到本地服务器或者云服务器的纯软件服务,也提供服务器、GPU一体机全包服务,提供视频设备管理、无插件、跨平台的实时视频、历史回放、语音对讲、设备控制等基础功能,支持视频协议有海康、大华私有协议…...
JVM基础:初识JVM
IDE:IntelliJ IDEA 2022.1.3 x64 操作系统:win10 x64 位 家庭版 文章目录 一、JVM是什么?二、JVM有哪些功能?2.1 解释和运行2.2 内存管理2.3 即时编译 三、有哪些常见的JVM?3.1 常见JVM3.2 Java虚拟机规范3.3 HotSpot的…...
至强服务器BIOS/UEFI驱动开发笔记
至强服务器BIOS/UEFI驱动开发笔记 驱动开发基础Hello UEFI Driver 项目选择项目位置初始化驱动代码文件结构驱动程序入口和基本功能导入AMI工程AMI平台Hello UEFI Driver 编译问题测试结果打印设备列表继续开发`HelloWorldSupported`函数依赖配置使用脚本编译编译测试此DXE驱动…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
