【C 数据结构】单链表
文章目录
- 【 1. 基本原理 】
- 1.1 链表的节点
- 1.2 头指针、头节点、首元节点
- 【 2. 链表的创建 】
- 2.0 创建1个空链表(仅有头节点)
- 2.1 创建单链表(头插入法)*
- 2.2 创建单链表(尾插入法)
- 【 3. 链表插入元素 】
- 【 4. 链表删除元素 】
- 【 5. 链表查找元素 】
- 【 6. 链表修改元素 】
- 【 7. 链表输出 】
- 【 8. 实例 - 链表元素的增删查改 】
- 【 9. 无头节点的链表 】
本文中若未指定,则默认链表存在首元结点。
【 1. 基本原理 】
- 与顺序表不同,链表 不限制数据的物理存储状态(存储空间是否连续) ,使用链表存储的数据元素,其 物理存储位置是随机的 。
- 例如,使用链表存储 1,2,3 ,数据的物理存储状态如图所示:
- 上图根本无法体现出各数据之间的逻辑关系。对此,链表的解决方案是,每个数据元素在存储时都配备一个指针,用于指向自己的直接后继元素:
- 数据元素随机存储,并通过指针表示数据之间逻辑关系 的存储结构就是 链式存储结构。
1.1 链表的节点
- 链表中每个数据的存储都由以下两部分组成:
- 数据元素本身,其所在的区域称为数据域;
- 指向直接后继元素的指针,所在的区域称为指针域;
- 链表中存储各数据元素的结构,即 节点。如图所示:
- 也就是说, 链表实际存储的是一个一个的节点,真正的数据元素包含在这些节点中,如图所示:
- 链表中每个节点的具体实现,需要使用 C 语言中的结构体, 每个节点都是一个结构体,具体实现代码为:
- 由于指针域中的指针要指向的也是一个节点,因此要声明为 Link 类型(这里要写成 struct Link* 的形式)。
//定义结点类型
typedef struct Node {int data; //数据类型,你可以把int型的data换成任意数据类型,包括结构体struct等复合类型struct Node *next; //单链表的指针域
} Node,*LinkedList;
//Node表示结点的类型,LinkedList表示指向Node结点类型的指针类型
1.2 头指针、头节点、首元节点
- 一个完整的链表需要由以下几部分构成:
- 头指针:一个普通的指针,它的特点是 永远指向链表第一个节点的位置。很明显,头指针用于指明链表的位置,便于后期找到链表并使用表中的数据;
- 节点:链表中的节点又细分为头节点、首元节点和其他节点:
- 头节点:其实就是一个 不存任何数据的空节点,通常作为链表的第一个节点。对于链表来说,头节点不是必须的,它的作用只是为了方便解决某些实际问题;链表中有头节点时,头指针指向头节点;反之,若链表中没有头节点,则头指针指向首元节点。
- 首元节点:由于头节点(也就是空节点)的缘故,链表中称 第一个存有数据的节点 为首元节点。首元节点只是对链表中第一个存有数据节点的一个称谓,没有实际意义;
- 其他节点:链表中其他的节点。
- 一个存储 {1,2,3} 的完整链表结构如图所示:
- 节点的创建,C实现:
Node *p=(Node *)malloc(sizeof(Node));//或者 Node* L = new Node;
【 2. 链表的创建 】
- 创建一个链表需要做如下工作:
- 声明一个头指针(如果有必要,可以声明一个头节点);
- 创建多个存储数据的节点,在创建的过程中,要随时与其前驱节点建立逻辑关系;
2.0 创建1个空链表(仅有头节点)
- 创建一个指向链表节点的指针,申请一块链表节点的内存,使该指针指向该块内存(若该指针指向空,表示内存申请失败,输出信息提示),最后将该指针指向的节点的指针域指向NULL空,表示该链表初始化后仅有1个节点。
Node* listinit(){Node *L;L=(Node*)malloc(sizeof(Node)); //开辟空间 if(L==NULL){ //判断是否开辟空间失败,这一步很有必要printf("申请空间失败");exit(0); //开辟空间失败可以考虑直接结束程序}L->next=NULL; //指针指向空return L;
}
2.1 创建单链表(头插入法)*
- 先创建一个头节点,头节点的指针域指向空。插入新节点时,将新节点的指针域指向头节点的next,再将头节点的next指向该新节点。
- C 实现
//单链表的建立1,头插法建立单链表
LinkedList LinkedListCreatH(int x[],int N) {Node* L;L = (Node*)malloc(sizeof(Node)); //申请头结点空间L->next = NULL; //初始化一个空链表for(int i=0;i<N;++i){Node* p;p = (Node*)malloc(sizeof(Node)); //申请新的结点p->data = x[i]; //结点数据域赋值p->next = L->next; //将结点插入到表头L-->|2|-->|1|-->NULLL->next = p;}return L;
}
2.2 创建单链表(尾插入法)
- 先创建一个头节点,头节点的指针域指向空,再创建一个尾指针,尾指针先指向头节点。插入新节点时,将尾指针的next指向该新节点,再将尾指针指向该新节点,最后将尾指针的next指空。
- C实现:
//单链表的建立2,尾插法建立单链表
LinkedList LinkedListCreatT(int x[], int N) {Node* L;L = (Node*)malloc(sizeof(Node)); //申请头结点空间L->next = NULL; //初始化一个空链表Node* r;r = L; //r始终指向尾节点,开始时指向头节点for (int i = 0; i < N; ++i) {Node* p;p = (Node*)malloc(sizeof(Node)); //申请新的结点p->data = x[i]; //结点数据域赋值r->next = p; //将结点插入到表头L-->|1|-->|2|-->NULLr = p;}r->next = NULL;return L;
}
【 3. 链表插入元素 】
- 链表插入元素只需做以下两步操作,即可将新元素插入到指定的位置:
1.将新结点的 next 指针指向插入位置后的结点;
2.将插入位置前结点的 next 指针指向插入结点; - 链表插入元素的操作必须是先步骤 1,再步骤 2;反之,若先执行步骤 2 即 将插入位置前结点的 next 指针指向插入结点,除非再添加一个指针,作为插入位置后续链表的头指针,否则会导致插入位置后的这部分链表丢失,无法再实现步骤 1。
- 例如,我们在链表 1,2,3,4 的基础上分别实现在头部、中间部位、尾部插入新元素 5,其实现过程如图所示:
- 从图中可以看出,虽然新元素的插入位置不同,但实现插入操作的方法是一致的,都是先执行步骤 1 ,再执行步骤 2。
- C 实现:指定位置插入元素
//单链表的插入
//在链表的第i个位置插入x的元素,若位置超过链表大小,则链表不改动
LinkedList LinkedListInsert(LinkedList L, int i, int x) {Node* pre; // pre为前驱结点pre = L;int j = 1;while (pre->next) {if (i == j++) {Node* p; //插入的结点为pp = (Node*)malloc(sizeof(Node));p->data = x;p->next = pre->next;pre->next = p;break;}pre = pre->next;} return L;
}
【 4. 链表删除元素 】
- 从链表中删除指定数据元素时,实则就是将存有该数据元素的节点从链表中摘除,但作为一名合格的程序员,要对存储空间负责,对不再利用的存储空间要及时释放 。因此,从链表中删除数据元素需要进行以下 2 步操作:
- 将要删除的节点的前一个节点的next指向要删除节点的next;
- 可选:手动释放掉要删除节点的内存。
例如,从存有 1,2,3,4 的链表中删除元素 3,则此代码的执行效果如图所示:
- C 实现:删除指定元素的节点
// 删除单链表中值为x的元素
// 若有相同元素值,默认删除离表头最近的元素
// 若链表不存在x,则链表不改动
LinkedList LinkedListDelete(LinkedList L, int x) {Node* p, * pre; //pre为前驱结点,p为查找的结点。p = L->next;pre = L;while (p) {if (p->data == x){pre->next = p->next; //删除操作,将其前驱next指向其后继。free(p);break;}pre = p;p = p->next;}return L;
}
- C实现:删除指定位置的节点
//p为原链表,add为要删除元素的位置
Node *delElem(Node * p, int add)
{Node * temp = p;//遍历到被删除结点的上一个结点for (int i = 1; i < add; i++){temp = temp->next;if (temp->next == NULL){printf("没有该结点\n");return p;}}Node * del = temp->next;//单独设置一个指针指向被删除结点,以防丢失temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域free(del);//手动释放该结点,防止内存泄漏return p;
}
【 5. 链表查找元素 】
- 从首元结点依次遍历表中节点,用被查找元素与各节点数据域中存储的数据元素进行比对,直至比对成功或遍历至链表最末端的 NULL(比对失败的标志)。
- C 实现:查找指定值的元素位置
// 查找单链表中的元素
// p为原链表,elem表示被查找元素,函数返回被查元素的位置,若返回值为-1表示链表中不存在该元素
int selectElem(Node* p, int elem)
{//新建一个指针t,初始化为头指针 pNode* t = p;int i = 1;//由于头节点的存在,因此while中的判断为t->nextwhile (t->next){t = t->next;if (t->data == elem)return i;i++;}//程序执行至此处,表示查找失败printf("该数据不存在\n");return -1;
}
【 6. 链表修改元素 】
- 更新链表中的元素,只需通过遍历找到存储此元素的节点,对节点中的数据域做更改操作即可。
- C 实现:修改指定位置的元素
//add 表示更改结点在链表中的位置,newElem 为新的数据域的值
Node *amendElem(Node * p,int add,int newElem)
{Node * temp=p;temp=temp->next;//在遍历之前,temp指向首元结点//遍历到待更新结点for (int i=1; i<add; i++) temp=temp->next;temp->elem=newElem;return p;
}
- C 实现:修改指定元素值
//将链表中值为x的元素全都变为k。
LinkedList LinkedListReplace(LinkedList L, int x, int k) {Node* p = L->next;int i = 0;while (p) {if (p->data == x) {p->data = k;}p = p->next;}return L;
}
【 7. 链表输出 】
- 首先创建一个链表节点的指针,指向首元结点,然后判断该指针是否指向了空,若非空,则输出该指针指向的节点的信息,然后指针指向下一个节点循环判断,直到该指针为空。
//输出单链表
void printList(LinkedList L){Node *p=L->next;int i=0;while(p){printf("第%d个元素的值为:%d\n",++i,p->data);p=p->next;}
}
【 8. 实例 - 链表元素的增删查改 】
- 对链表中数据元素做"增删查改"的实现过程及 C 语言代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>//定义结点类型
typedef struct Node
{int data; //数据类型,可以把int型的data换成任意数据类型,包括结构体struct等复合类型struct Node* next; //单链表的指针域
} Node, * LinkedList;//建立单链表,尾插法
LinkedList LinkedListCreatT(int x[], int N) {Node* L;L = (Node*)malloc(sizeof(Node)); //申请头结点空间L->next = NULL; //初始化一个空链表Node* r;r = L; //r始终指向终端结点,开始时指向头结点for (int i = 0; i < N; ++i) {Node* p;p = (Node*)malloc(sizeof(Node)); //申请新的结点p->data = x[i]; //结点数据域赋值r->next = p; //将结点插入到表头L-->|1|-->|2|-->NULLr = p;}r->next = NULL;return L;
}// 查找单链表中的元素
// p为原链表,elem表示被查找元素,函数返回被查元素的位置,若返回值为-1表示链表中不存在该元素
int selectElem(Node* p, int elem)
{//新建一个指针t,初始化为头指针 pNode* t = p;int i = 1;//由于头节点的存在,因此while中的判断为t->nextwhile (t->next){t = t->next;if (t->data == elem)return i;i++;}//程序执行至此处,表示查找失败printf("该数据不存在\n");return -1;
}//单链表的插入
//在链表的第i个位置插入x的元素,若位置超过链表大小,则链表不改动
LinkedList LinkedListInsert(LinkedList L, int i, int x) {Node* pre; //pre为前驱结点pre = L;int j = 1;while (pre->next) {if (i == j++) {Node* p; //插入的结点为pp = (Node*)malloc(sizeof(Node));p->data = x;p->next = pre->next;pre->next = p;break;}pre = pre->next;} return L;
}// 删除单链表中值为x的元素
// 若有相同元素值,默认删除离表头最近的元素
// 若链表不存在x,则链表不改动
LinkedList LinkedListDelete(LinkedList L, int x) {Node* p, * pre; //pre为前驱结点,p为查找的结点。p = L->next;pre = L;while (p) {if (p->data == x){pre->next = p->next; //删除操作,将其前驱next指向其后继。free(p);break;}pre = p;p = p->next;}return L;
}//将链表中值为x的元素全都变为k。
LinkedList LinkedListReplace(LinkedList L, int x, int k) {Node* p = L->next;int i = 0;while (p) {if (p->data == x) {p->data = k;}p = p->next;}return L;
}//输出单链表
void printList(LinkedList L) {Node* p = L->next;int i = 0;while (p) {printf("第%d个元素的值为:%d\n", ++i, p->data);p = p->next;}
}int main() {int N;printf("请输入链表的数量:");scanf("%d", &N);printf("请输入链表的元素:");int *x=new int[N];for (int i = 0; i < N; ++i)scanf("%d",&x[i]);//创建LinkedList list;list = LinkedListCreatT(x,N);printList(list);//插入 int pos;int data;printf("请输入插入数据的位置:");scanf("%d", &pos);printf("请输入插入数据的值:");scanf("%d", &data);LinkedListInsert(list, pos, data);printList(list);//查找printf("请输入查找数据的值:");scanf("%d", &data);printf("该数据在链表中的位置为%d\n",selectElem(list, data));//修改int newdata;printf("请输入修改的数据:");scanf("%d", &data);printf("请输入修改后的值:");scanf("%d", &newdata);LinkedListReplace(list, data, newdata);printList(list);//删除 printf("请输入要删除的元素的值:");scanf("%d", &data);LinkedListDelete(list, data);printList(list);return 0;
}
【 9. 无头节点的链表 】
- 创建一个无头节点的链表,C 实现:
//创建1个有头节点的单链表
Node* LinkedListCreatN(int x[], int N) {Node* L = (Node*)malloc(sizeof(Node));L->data = x[0];L->next = NULL;Node* p = L; //p作为尾节点指针for (int i = 1; i < N; ++i) {Node *temp = (Node *) malloc(sizeof(Node));temp->data = x[i];temp->next = NULL;p->next = temp;p = temp;}return L;
}
- 输出无头节点的单链表各个元素,C实现:
//输出单链表
void printList(LinkedList L) {Node* p = L;int i = 0;while (p) {printf("第%d个元素的值为:%d\n", ++i, p->data);p = p->next;}
}
- 删除无头节点的单链表的指定元素,C实现:
当删除的元素是第一个节点时,为了方便处理,这里事先申请一块内存,该内存的next指针域指向该链表的头节点,相当于作为 pre 前指针。
//删除链表中第一个值为x的元素
Node* DeleteList(Node* L, int x) {Node* temptou = (Node*)malloc(sizeof(Node));temptou->next = L;Node* pre=temptou;Node* cur=pre->next;while (cur){if (cur->data == x) {pre->next = cur->next;free(cur);break;}pre = cur;cur = cur->next;}return temptou->next;
}
- 实例
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>//定义结点类型
typedef struct Node
{int data; //数据类型,可以把int型的data换成任意数据类型,包括结构体struct等复合类型struct Node* next; //单链表的指针域
} Node;//创建1个有头节点的单链表
Node* LinkedListCreatN(int x[], int N) {Node* L = (Node*)malloc(sizeof(Node));L->data = x[0];L->next = NULL;Node* p = L; //p作为尾节点指针for (int i = 1; i < N; ++i) {Node* temp = (Node*)malloc(sizeof(Node));temp->data = x[i];temp->next = NULL;p->next = temp;p = temp;}return L;
}//删除链表中第一个值为x的元素
Node* DeleteList(Node* L, int x) {Node* temptou = (Node*)malloc(sizeof(Node));temptou->next = L;Node* pre=temptou;Node* cur=pre->next;while (cur){if (cur->data == x) {pre->next = cur->next;free(cur);break;}pre = cur;cur = cur->next;}return temptou->next;
}//输出单链表
void printList(Node* L) {Node* p = L;int i = 0;while (p){printf("第%d个元素的值为:%d\n", ++i, p->data);p = p->next;}
}int main() {int N;printf("请输入链表的元素数量:");scanf("%d", &N);printf("请输入链表的元素:");int* x = new int[N];for (int i = 0; i < N; ++i)scanf("%d", &x[i]);//创建Node* list;list = LinkedListCreatN(x, N);printList(list);//删除int data;printf("请输入要删除的元素值:");scanf("%d",&data);Node* listtemp;listtemp = DeleteList(list, data);printList(listtemp);return 0;
}
相关文章:
【C 数据结构】单链表
文章目录 【 1. 基本原理 】1.1 链表的节点1.2 头指针、头节点、首元节点 【 2. 链表的创建 】2.0 创建1个空链表(仅有头节点)2.1 创建单链表(头插入法)*2.2 创建单链表(尾插入法) 【 3. 链表插入元素 】【…...
[MAUI]集成富文本编辑器Editor.js至.NET MAUI Blazor项目
文章目录 获取资源从源码构建从CDN获取获取扩展插件 创建项目创建控件创建Blazor组件初始化保存销毁编写渲染逻辑 实现只读/编辑功能切换模式获取只读模式状态响应切换事件 实现明/暗主题切换项目地址 Editor.js 是一个基于 Web 的所见即所得富文本编辑器,它由CodeX…...
Spring Boot | Spring Boot 整合 “Servlet三大组件“ ( Servlet / Filter / Listene )
目录: Spring Boot 整合 "Servlet三大组件" :1. 使用 "组件注册" 的方式 "整合Servlet三大组件" ( 实际操作为 : 创建自定义的"三大组件"对象 结合刚创建"的自定义组件对象"来 将 XxxRegistrationBean对象 通过…...
错误分析 (Machine Learning研习十九)
错误分析 您将探索数据准备选项,尝试多个模型,筛选出最佳模型,使用 Grid SearchCV微调其超参数,并尽可能实现自动化。在此,我们假设您已经找到了一个有前途的模型,并希望找到改进它的方法。其中一种方法就…...
SQL系统函数知识点梳理(Oracle)
这里写目录标题 函数系统函数转换函数to_date()to_char()将数值转换成字符格式 添加货币符号将日期转换成字符 其他不常用的转换函数 字符型函数连接函数大小写转换函数大写转换小写转换首字母大写,其余的小写 替换函数去除空格函数截取函数填充函数获取字符长度函数…...
面试突击---MySQL索引
面试突击---MYSQL索引 面试表达技巧:1、谈一下你对于mysql索引的理解?(为什么mysql要选择B树来存储索引)2、索引有哪些分类?3、聚簇索引与非聚簇索引4、回表、索引覆盖、最左匹配原则、索引下推(1ÿ…...
关注 | 我国已对百种产品实施强制性产品认证
市场监管总局在7日举行的新闻发布会上介绍,该局日前发布《市场监管总局关于对商用燃气燃烧器具等产品实施强制性产品认证管理的公告》,对具有较高安全风险的商用燃气燃烧器具、阻燃电线电缆、电子坐便器、电动自行车乘员头盔、可燃气体探测报警产品、水性…...
虚幻引擎架构自动化及蓝图编辑器高级开发进修班
课程名称:虚幻引擎架构自动化及蓝图编辑器高级开发进修班 课程介绍 大家好 我们即将推出一套课程 自动化系统开发。 自动化技术在项目开发的前中后期都大量运用。如何您是一家游戏公司,做的是网络游戏,是不是经常会遇到程序员打包加部署需…...
Weakly Supervised Audio-Visual Violence Detection 论文阅读
Weakly Supervised Audio-Visual Violence Detection 论文阅读 摘要III. METHODOLOGYA. Multimodal FusionB. Relation Modeling ModuleC. Training and Inference IV. EXPERIMENTSV. CONCLUSION阅读总结 文章信息: 发表于:IEEE TRANSACTIONS ON MULTIME…...
华为海思数字芯片设计笔试第六套
声明 下面的题目作答都是自己认为正确的答案,并非官方答案,如果有不同的意见,可以评论区交流。 这些题目也是笔者从各个地方收集的,感觉有些题目答案并不正确,所以在个别题目会给出自己的见解,欢迎大家讨论…...
重绘和重排:概念、区别和应用示例
还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,ech…...
创建k8s deploy yaml文件的imagePullSecrets语句
镜像仓库是harbor kubectl create secret docker-registry key --docker-server192.168.0.190 --docker-usernameadmin --docker-passwordHarbor12345...
大模型预测结果导入到Doccano,人工修正预测不准的数据
背景 使用大语言模型做实体识别的实验时,发现大模型关于实体的边界预测一直不准。 主要原因在于当时找了很多同学标注数据,由于不同组同学关于实体的边界没有统一,故导致数据集中实体边界也没统一。 (找太多人标,会有…...
python三方库_ciscoconfparse学习笔记
文章目录 介绍使用基本原理父子关系 属性ioscfg 获取配置信息,返回列表is_config_line 判断是否是配置行is_intf 判断IOSCfgLine是不是interfaceis_subintf 判断IOSCfgLine是不是子接口lineage 不知道用法is_ethernet_intf 判断IOSCfgLine是否是以太网接口is_loopback_intf 判断…...
HDFS详解(Hadoop)
Hadoop 分布式文件系统(Hadoop Distributed File System,HDFS)是 Apache Hadoop 生态系统的核心组件之一,它是设计用于存储大规模数据集并运行在廉价硬件上的分布式文件系统。 1. 分布式存储: HDFS 将文件分割成若干块…...
python创建word文档并向word中写数据
一、docx库的安装方法 python创建word文档需要用到docx库,安装命令如下: pip install python-docx 注意,安装的是python-docx。 二、使用方法 使用方法有很多,这里只介绍创建文档并向文档中写入数据。 import docxmydocdocx.Do…...
MongoDB的安装配置及使用
文章目录 前言一、MongoDB的下载、安装、配置二、检验MongoDB是否安装成功三、Navicat 操作MongoDB四、创建一个集合,存放三个文档总结 前言 本文内容: 💫 MongoDB的下载、安装、配置 💫 检验MongoDB是否安装成功 ❤️ Navicat 操…...
Go学习路线
Go学习路线 文章目录 Go学习路线入门阶段一、Go基础和Goland的安装二、学习日志文件及配置文件三、学习mysql四、html,css,js快速入门五、写一个简单的前后端分离的记事本项目六、Linux快速入门七、Docker快速入门八、Git命令快速入门九、使用Docker打包…...
安全大脑与盲人摸象
21世纪是数字科技和数字经济爆发的时代,互联网正从网状结构向类脑模型进行进化,出现了结构和覆盖范围庞大,能够适应不同技术环境、经济场景,跨地域、跨行业的类脑复杂巨型系统。如腾讯、Facebook等社交网络具备的神经网络特征&…...
如何使用Git-Secrets防止将敏感信息意外上传至Git库
关于Git-Secrets Git-secrets是一款功能强大的开发安全工具,该工具可以防止开发人员意外将密码和其他敏感信息上传到Git库中。 Git-secrets首先会扫描提交的代码和说明,当与用户预先配置的正则表达式模式匹配时,便会阻止此次提交。该工具的优…...
Day 14 网络协议
常见网络设备:交换机 路由器 中继器 多协议网关(路由器的前身) 交换机:用于连接统一网络的设备,实现内网设备通信。 从广义上分为:局域网交换机,广域网交换机 从网络构成分为:接…...
msyql中SQL 错误 [1118] [42000]: Row size too large (> 8126)
场景: CREATE TABLE test-qd.eqtree (INSERT INTO test.eqtree (idocid VARCHAR(50) NULL,sfcode VARCHAR(50) NULL,sfname VARCHAR(50) NULL,sfengname VARCHAR(50) NULL,…… ) ENGINEInnoDB DEFAULT CHARSETutf8 COLLATEutf8_general_ci;或 alter table eqtre…...
实验六 智能手机互联网程序设计(微信程序方向)实验报告
实验目的和要求 请完成创建图片库应用,显示一系列预设的图片。 提供按钮来切换显示不同类别的图片。 二、实验步骤与结果(给出对应的代码或运行结果截图) 1.WXML <view> <button bindtap"showAll">所有图片</but…...
Linux环境下,让Jar项目多线程部署成为可能
欢迎来到我的博客,代码的世界里,每一行都是一个故事 Linux环境下,让Jar项目多线程部署成为可能 前言背景介绍使用sh脚本实现使用systemd来实现使用docker-compose实现 前言 在当今互联网时代,应用程序的高可用性和性能是至关重要…...
k8s调度场景
15个KUBERNETES调度情景实用指南 Kubernetes调度是确保集群中的Pod在适当节点上运行的关键组件。通过灵活配置调度策略,可以提高资源利用率、负载平衡和高可用性。 在本文中,我们将深入探讨一些实际的Kubernetes调度场景,并提供相应的配置示…...
基于小程序实现的餐饮外卖系统
作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:spring…...
家居网购项目(手写分页)
文章目录 1.后台管理—分页显示1.程序框架图2.编写数据模型Page.java 3.编写dao层1.修改FurnDao增加方法 2.修改FurnDaoImpl增加方法 3.单元测试FurnDaoTest 4.编写service层1.修改FurnService增加方法 2.修改FurnServiceImpl增加方法3.单元测试FurnServiceTest 5.编写DataUtil…...
goland2024安装包(亲测可用)
目录 一、软件简介 二、软件下载 一、软件简介 Goland 是一款由 JetBrains 公司开发的集成开发环境(IDE),专门用于 Go 语言的开发。它提供了丰富的功能和工具,帮助开发者更高效地编写、调试和管理 Go 语言项目。 功能特点&#x…...
35、链表-LRU缓存
思路: 首先要了解LRU缓存的原理,首先定下容量,每次get请求和put请求都会把当前元素放最前/后面,如果超过容量那么头部/尾部元素就被移除,所以最近最少使用的元素会被优先移除,保证热点数据持续存在。 不管放…...
数据结构速成--栈
由于是速成专题,因此内容不会十分全面,只会涵盖考试重点,各学校课程要求不同 ,大家可以按照考纲复习,不全面的内容,可以看一下小编主页数据结构初阶的内容,找到对应专题详细学习一下。 目录 一…...
算法练习第15天|226.翻转二叉树
226.翻转二叉树 力扣链接https://leetcode.cn/problems/invert-binary-tree/description/ 题目描述: 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出&am…...
C#面向对象——封装、封装案例示例
C#面向对象——封装 什么是封装? (1)封装是将数据和操作数据的方法(行为)封装在一起。 (2)程序中封装的体现:属性,方法,类,接口,命名空间&#…...
【InternLM 实战营第二期-笔记3】茴香豆:搭建你的 RAG 智能助理
书生浦语是上海人工智能实验室和商汤科技联合研发的一款大模型,很高兴能参与本次第二期训练营,我也将会通过笔记博客的方式记录学习的过程与遇到的问题,并为代码添加注释,希望可以帮助到你们。 记得点赞哟(๑ゝω╹๑) 茴香豆:搭建…...
Advanced RAG 03:运用 RAGAs 与 LlamaIndex 评估 RAG 应用
编者按:目前,检索增强生成(Retrieval Augmented Generation,RAG)技术已经广泛使用于各种大模型应用场景。然而,如何准确评估 RAG 系统的性能和效果,一直是业界和学界共同关注的重点问题。若无法…...
leetcode
找到字符串中所有字母异位词 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串(包括相同的字符串) 示例 1: 输入: s "…...
Unity DOTS《群体战斗弹幕游戏》核心技术分析之3D角色动画
最近DOTS发布了正式的版本, 我们来分享现在流行基于群体战斗的弹幕类游戏,实现的核心原理。今天给大家介绍大规模战斗群体3D角色的动画如何来实现。 DOTS 对角色动画支持的局限性 截止到Unity DOTS发布的版本1.0.16,目前还是无法很好的支持3D角色动画。在DOTS 的ba…...
react异步组件如何定义使用 标准使用方法
目录 默认导出和命名导出的格式 默认导出的组件 使用方式 命名导出的组件 使用方式 默认导出和命名导出的格式 默认导出: // person.js const person {name: Alice,age: 30 };export default person;命名导出: // math.js export const add (a, b) > a b; exp…...
React + Ts + Vite + Antd 项目搭建
1、创建项目 npm create vite 项目名称 选择 react 选择 typescript 关闭严格模式 建议关闭严格模式,因为不能自动检测副作用,有意双重调用。将严格模式注释即可。 2、配置sass npm install sass 更换所有后缀css为sass vite.config.ts中注册全局样式 /…...
js爬虫puppeteer库 解决网页动态渲染无法爬取
我们爬取这个网址上面的股票实时部分宇通客车(600066)_股票价格_行情_走势图—东方财富网 我们用正常的方法爬取会发现爬取不下来,是因为这个网页这里是实时渲染的,我们直接通过网址接口访问这里还没有渲染出来 于是我们可以通过下面的代码来进行爬取: …...
代码随想录:二叉树5
目录 102.二叉树的层序遍历 题目 代码(队列实现) 107.二叉树的层序遍历II 题目 代码 199.二叉树的右视图 题目 代码 637.二叉树的层平均值 题目 代码 102.二叉树的层序遍历 题目 给你二叉树的根节点 root ,返回其节点值的 层序遍…...
Tomcat 获取客户端真实IP X-Forwarded-For
Tomcat 获取客户端真实IP X-Forwarded-For 代码实现: 在Host标签下面添加代码: <Valve className"org.apache.catalina.valves.RemoteIpValve" remoteIpHeader"x-forwarded-for" remoteIpProxiesHeader"x-forwarded-by&q…...
记录PS学习查漏补缺
PS学习 PS学习理论快捷键抠图PS专属多软件通用快捷键 PS学习 理论 JPEG (不带透明通道) PNG (带透明通道) 快捷键 抠图 抠图方式 魔棒工具 反选选中区域 CtrlShiftI(反选) 钢笔抠图注意事项 按着Ctrl单击节点 会出现当前节…...
Kafka 架构深入探索
目录 一、Kafka 工作流程及文件存储机制 二、数据可靠性保证 三 、数据一致性问题 3.1follower 故障 3.2leader 故障 四、ack 应答机制 五、部署FilebeatKafkaELK 5.1环境准备 5.2部署ELK 5.2.1部署 Elasticsearch 软件 5.2.1.1修改elasticsearch主配置文件 5.2…...
k-means聚类算法的MATLAB实现及可视化
K-means算法是一种无监督学习算法,主要用于数据聚类。其工作原理基于迭代优化,将数据点划分为K个集群,使得每个数据点都属于最近的集群,并且每个集群的中心(质心)是所有属于该集群的数据点的平均值。以下是…...
Excel文件转Asc文件
单个转换 import os import pandas as pdfilename (10)result01-1.xlsx df pd.read_excel(filename) # 读取Excel文件# 将数据保存为ASC格式 asc_filename os.path.splitext(filename)[0] .asc # 获取文件名并替换扩展名 with open(asc_filename, w) as file:# 写入文件…...
【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题7
【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题7 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书,赛题,解析等资料,知识点培训服务 添加博主wx:liuliu548…...
Webrtc 信令服务器实现
webrtc建联流程图 由上图可知,所谓的信令服务器其实就是将peer的offer/candidate/answer传给对端而已。这样的话实现方式就有很多种了,目前普遍的方式HTTP/HTTPS,WS/WSS。像webrtc-demo-peerconnection就是实现HTTP这种方式。本文使用WS&…...
【Blockchain】连接智能合约与现实世界的桥梁Chainlink
去中心化预言机试图实现依赖因果关系而不是个人关系的去信任和确定性结果。它以与区块链网络相同的方式实现这些结果,即在许多网络参与者之间分配信任。通过利用许多不同的数据源并实施不受单个实体控制的预言机系统,去中心化的预言机网络有可能为智能合…...
解决EasyPoi导入Excel获取不到第一列的问题
文章目录 1. 复现错误2. 分析错误2.1 导入的代码2.2 DictExcel实体类2.2 表头和标题3. 解决问题1. 复现错误 使用EasyPoi导入数据时,Excel表格如下图: 但在导入时,出现如下错误: name为英文名称,在第一列,Excel表格有值,但导入的代码中为null,就很奇怪? 2. 分析错误 …...
Vue 阶段练习:记事本
将 Vue快速入门 和 Vue 指令的学习成果应用到实际场景中(如该练习 记事本),我们能够解决实际问题并提升对 Vue 的技能掌握。 目录 功能展示 需求分析 我的代码 案例代码 知识点总结 功能展示 需求分析 列表渲染删除功能添加功能底部统计…...