学习记录day16—— 数据结构 双向链表 循环链表
双向链表
1、概念
1)就是从任意一个节点既能存储其前驱节点,又能存储后继节点
2)结构体中增加一个指向前驱节点的指针
//定义数据类型
typedef int datatype;//定义节点类型
typedef struct Node
{union {int len;datatype data;};struct Node *prio; struct Node *next; };
3)头节点没有前驱,最后一个节点没有后继
2、创建虚拟链表
// 创建链表
NodePtr list_create()
{// 在堆区申请一个头节点NodePtr L = (NodePtr)malloc(sizeof(Node));if (NULL == L){printf("创建失败\n");return NULL;}L->len = 0;L->next = NULL;L->prio = NULL;printf("链表创建成功\n");return L;
}
3、申请封装数据
// 申请封装数据
NodePtr apply_node(datatype e)
{NodePtr p = (NodePtr)malloc(sizeof(Node));if (NULL == p){printf("数据类型不合法,封装失败\n");return NULL;}p->data = e;p->prio = NULL;p->next = NULL;return p;
}
4、判空
// 判空
int list_empty(NodePtr L)
{return L->next == NULL;
}
5、头插

// 头插
int list_insert_head(NodePtr L, datatype e)
{if (NULL == L){printf("数据类型不合法,头插失败\n");return -1;}NodePtr p = apply_node(e);if (NULL == p){printf("数据封装失败,头插失败\n");return -1;}if (list_empty(L)){p->prio = L;L->next = p;}else{p->prio = L;p->next = L->next;L->next->prio = p; // p->next->prio =p;L->next = p;}L->len++;printf("插入成功\n");return 0;
}
6、链表遍历
// 链表遍历
int list_show(NodePtr L)
{if (NULL == L || list_empty(L)){printf("遍历失败\n");return -1;}NodePtr q = L->next; // 定义遍历指针从第一个节点出发while (q){// 输出数据域printf("%c", q->data);q = q->next; // 指针指向下一数据域}putchar(10);printf("遍历结束\n");
}
7、按完整查找
// 按位置查找
NodePtr list_search_pos(NodePtr L,datatype pos)
{if (NULL == L || list_empty(L) || pos > L->len || pos < 0){printf("查找失败\n");return NULL;}NodePtr q = L;for(int i = 0;i < pos ; i++){q = q->next;}printf("查找成功\n");return q;
}
8、按位置删除
// 按位置删除
int list_delete_pos(NodePtr L,datatype pos)
{if (NULL == L || list_empty(L) || pos < 1 || pos > L->len){printf("按位置删除失败\n");return -1;}NodePtr q = list_search_pos(L,pos);if (q->next == NULL){q->prio->next = NULL;}else{// q->next->prio = q->prio;// q->next->prio->next = q->next;q->prio->next = q->next;q->next->prio = q->prio;}L->len--;free(q);q = NULL;printf("删除成功\n");return 0;
}
9、链表删除
// 链表删除
void list_destroy(NodePtr L)
{if (NULL == L ){printf("删除失败\n");return;}while (L->next/*!(list_empty(L))*/){list_delete_pos(L,1);}if (L->next = NULL){free(L);L->next = NULL;}printf("删除成功\n");return ;
}
10、完整代码
00.h
#ifndef day16_flag_h
#define day16_flag_h
#include <myhead.h>typedef char datatype;typedef struct Node
{union {int len;datatype data;};struct Node *prio;struct Node *next;}Node,*NodePtr;NodePtr list_create();int list_empty(NodePtr L);NodePtr apply_node(datatype e);int list_insert_head(NodePtr l,datatype e);int list_show(NodePtr L);int list_search(NodePtr L,datatype pos);int list_delete_pos(NodePtr L,datatype e);void list_destroy(NodePtr L);#endif // day16_flag_h
00.c
#include "00.h"
#define MAX 50// 创建链表
NodePtr list_create()
{// 在堆区申请一个头节点NodePtr L = (NodePtr)malloc(sizeof(Node));if (NULL == L){printf("创建失败\n");return NULL;}L->len = 0;L->next = NULL;L->prio = NULL;printf("链表创建成功\n");return L;
}// 判空
int list_empty(NodePtr L)
{return L->next == NULL;
}// 申请封装数据
NodePtr apply_node(datatype e)
{NodePtr p = (NodePtr)malloc(sizeof(Node));if (NULL == p){printf("数据类型不合法,封装失败\n");return NULL;}p->data = e;p->prio = NULL;p->next = NULL;return p;
}// 头插
int list_insert_head(NodePtr L, datatype e)
{if (NULL == L){printf("数据类型不合法,头插失败\n");return -1;}NodePtr p = apply_node(e);if (NULL == p){printf("数据封装失败,头插失败\n");return -1;}if (list_empty(L)){p->prio = L;L->next = p;}else{p->prio = L;p->next = L->next;L->next->prio = p; // p->next->prio =p;L->next = p;}L->len++;printf("插入成功\n");return 0;
}// 链表遍历
int list_show(NodePtr L)
{if (NULL == L || list_empty(L)){printf("遍历失败\n");return -1;}NodePtr q = L->next; // 定义遍历指针从第一个节点出发while (q){// 输出数据域printf("%c", q->data);q = q->next; // 指针指向下一数据域}putchar(10);printf("遍历结束\n");
}// 按位置查找
NodePtr list_search_pos(NodePtr L,datatype pos)
{if (NULL == L || list_empty(L) || pos > L->len || pos < 0){printf("查找失败\n");return NULL;}NodePtr q = L;for(int i = 0;i < pos ; i++){q = q->next;}printf("查找成功\n");return q;
}// 按位置删除
int list_delete_pos(NodePtr L,datatype pos)
{if (NULL == L || list_empty(L) || pos < 1 || pos > L->len){printf("按位置删除失败\n");return -1;}NodePtr q = list_search_pos(L,pos);if (q->next == NULL){q->prio->next = NULL;}else{// q->next->prio = q->prio;// q->next->prio->next = q->next;q->prio->next = q->next;q->next->prio = q->prio;}L->len--;free(q);q = NULL;printf("删除成功\n");return 0;
}// 链表删除
void list_destroy(NodePtr L)
{if (NULL == L ){printf("删除失败\n");return;}while (L->next/*!(list_empty(L))*/){list_delete_pos(L,1);}if (L->next = NULL){free(L);L->next = NULL;}printf("删除成功\n");return ;
}
00main.c
#include "00.h"int main(int argc, char const *argv[])
{NodePtr L = list_create();if (NULL == L ){return -1;}list_insert_head(L,'H');list_show(L);list_insert_head(L,'e');list_show(L);list_insert_head(L,'l');list_show(L);list_insert_head(L,'l');list_show(L);list_insert_head(L,'o');list_show(L);list_delete_pos(L,1);list_show(L);list_delete_pos(L,2);list_show(L);list_delete_pos(L,L->len);list_show(L);list_destroy(L);list_show(L);return 0;
}
单向循环链表
1、概念
1)循环链表,就是首尾相接的链表
2)循环链表,就是首尾相接的链表
3)双向循环链表:需要将最后一个阶段的指针域指向头结点,头结点的前驱指针指向最后一 个阶段
2、循环链表的创建
1)创建虚拟链表
// 创建链表
NodePtr list_create()
{// 在堆区申请一个头节点NodePtr L = (NodePtr)malloc(sizeof(Node));if (NULL == L){printf("创建失败\n");return NULL;}L->len = 0;L->next = NULL;L->prio = NULL;printf("链表创建成功\n");return L;
}
2)判空
// 判空
int list_empty(NodePtr L)
{return L->next == L;
}
3)申请封装数据
// 申请封装数据
NodePtr apply_node(datatype e)
{NodePtr p = (NodePtr)malloc(sizeof(Node));if (NULL == p){printf("数据类型不合法,封装失败\n");return NULL;}p->data = e;p->next = NULL;return p;
}
4)按位置查找
// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{if (NULL == L || list_empty(L) || pos > L->len || pos < 0){printf("查找失败\n");return NULL;}NodePtr q = L;for (int i = 0; i < pos; i++){q = q->next;}printf("查找成功\n");return q;
}
5)头插
// 头插
int list_insert_head(NodePtr L, datatype e)
{// 判断逻辑if (NULL == L){printf("插入失败\n");return -1;}NodePtr p = apply_node(e);if (NULL == p){printf("封装失败\n");return -1;}p->next = L->next;L->next = p;L->len++;printf("插入成功\n");return 0;
}
6)尾插
// 尾插
int list_insert_tail(NodePtr L, datatype e)
{// 判断逻辑if (NULL == L){printf("尾插插入失败\n");return -1;}// 找到最后一个节点NodePtr q = list_search_pos(L, L->len);// 封装节点NodePtr p = apply_node(e);// 插入逻辑p->next = q->next;q->next = p;L->len++;printf("尾插插入成功\n");return 0;
}
7)头删
//头删
int list_delete_head(NodePtr L)
{if (NULL == L || list_empty(L)){printf("头删失败\n");return -1;}NodePtr p = L->next;L->next = p->next;free(p);p = NULL;L->len--;printf("头删成功\n");return 0;
}
8)链表删除
// 链表删除
void list_destroy(NodePtr L)
{if (NULL == L ){printf("删除失败\n");return;}while (L->next == L){list_delete_head(L);}free(L);L = NULL;printf("删除成功\n");return ;
}
9)完整代码
00.h
#ifndef day16_1_flag_h
#define day16_1_flag_h
#include <myhead.h>typedef char datatype;typedef struct Node
{union {int len;datatype data;};struct Node *next;}Node,*NodePtr;NodePtr list_create();int list_empty(NodePtr L);NodePtr apply_node(datatype e);NodePtr list_search_pos(NodePtr L,datatype pos);int list_insert_tail(NodePtr L,datatype e);int list_insert_head(NodePtr L,datatype e);int list_show(NodePtr L);int list_delete_head(NodePtr L);void list_destroy(NodePtr L);#endif // day16_1_flag_h
00.c
#include "00.h"
#define MAX 50// 创建链表
NodePtr list_create()
{// 在堆区申请一个头节点NodePtr L = (NodePtr)malloc(sizeof(Node));if (NULL == L){printf("创建失败\n");return NULL;}L->len = 0;L->next = L; // 头节点指针域指向自己printf("链表创建成功\n");return L;
}// 判空
int list_empty(NodePtr L)
{return L->next == L;
}// 申请封装数据
NodePtr apply_node(datatype e)
{NodePtr p = (NodePtr)malloc(sizeof(Node));if (NULL == p){printf("数据类型不合法,封装失败\n");return NULL;}p->data = e;p->next = NULL;return p;
}// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{if (NULL == L || list_empty(L) || pos > L->len || pos < 0){printf("查找失败\n");return NULL;}NodePtr q = L;for (int i = 0; i < pos; i++){q = q->next;}printf("查找成功\n");return q;
}// 头插
int list_insert_head(NodePtr L, datatype e)
{// 判断逻辑if (NULL == L){printf("插入失败\n");return -1;}NodePtr p = apply_node(e);if (NULL == p){printf("封装失败\n");return -1;}p->next = L->next;L->next = p;L->len++;printf("插入成功\n");return 0;
}// 尾插
int list_insert_tail(NodePtr L, datatype e)
{// 判断逻辑if (NULL == L){printf("尾插插入失败\n");return -1;}// 找到最后一个节点NodePtr q = list_search_pos(L, L->len);// 封装节点NodePtr p = apply_node(e);// 插入逻辑p->next = q->next;q->next = p;L->len++;printf("尾插插入成功\n");return 0;
}//链表遍历
int list_show(NodePtr L)
{if (NULL == L || list_empty(L)){printf("遍历失败\n");return -1;}NodePtr q = L->next;while(q !=L){printf("%c",q->data);q = q->next;}putchar(10);printf("遍历成功\n");return 0;
}//头删
int list_delete_head(NodePtr L)
{if (NULL == L || list_empty(L)){printf("头删失败\n");return -1;}NodePtr p = L->next;L->next = p->next;free(p);p = NULL;L->len--;printf("头删成功\n");return 0;
}// 链表删除
void list_destroy(NodePtr L)
{if (NULL == L ){printf("删除失败\n");return;}while (L->next == L){list_delete_head(L);}free(L);L = NULL;printf("删除成功\n");return ;
}
00main.c
#include "00.h"int main(int argc, char const *argv[])
{NodePtr L = list_create();if (NULL == L ){return -1;}list_insert_head(L,'H');list_show(L);list_insert_head(L,'e');list_show(L);list_insert_head(L,'l');list_show(L);list_insert_head(L,'l');list_show(L);list_insert_head(L,'o');list_show(L);list_insert_tail(L,'Z');list_show(L);list_delete_head(L);list_show(L);list_destroy(L);list_show(L);return 0;
}
10)约瑟夫环问题
00.h
#ifndef day16_1_flag_h
#define day16_1_flag_h
#include <myhead.h>typedef int datatype;typedef struct Node
{union {int len;datatype data;};struct Node *next;}Node,*NodePtr;NodePtr list_create();int list_empty(NodePtr L);NodePtr apply_node(datatype e);NodePtr list_search_pos(NodePtr L,datatype pos);int list_insert_tail(NodePtr L,datatype e);int list_insert_head(NodePtr L,datatype e);int list_show(NodePtr L);int list_delete_head(NodePtr L);void list_destroy(NodePtr L);// 任意位置删除
int list_delete_pos(NodePtr L, int pos);//按位置取值
int list_pos_value(NodePtr L,int pos);
#endif // day16_1_flag_h
00.c
#include "00.h"
#define MAX 50// 创建链表
NodePtr list_create()
{// 在堆区申请一个头节点NodePtr L = (NodePtr)malloc(sizeof(Node));if (NULL == L){printf("创建失败\n");return NULL;}L->len = 0;L->next = L; // 头节点指针域指向自己printf("链表创建成功\n");return L;
}// 判空
int list_empty(NodePtr L)
{return L->next == L;
}// 申请封装数据
NodePtr apply_node(datatype e)
{NodePtr p = (NodePtr)malloc(sizeof(Node));if (NULL == p){printf("数据类型不合法,封装失败\n");return NULL;}p->data = e;p->next = NULL;return p;
}// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{if (NULL == L || list_empty(L) || pos > L->len || pos < 0){printf("查找失败\n");return NULL;}NodePtr q = L;for (int i = 0; i < pos; i++){q = q->next;}printf("查找成功\n");return q;
}// 头插
int list_insert_head(NodePtr L, datatype e)
{// 判断逻辑if (NULL == L){printf("插入失败\n");return -1;}NodePtr p = apply_node(e);if (NULL == p){printf("封装失败\n");return -1;}p->next = L->next;L->next = p;L->len++;printf("插入成功\n");return 0;
}// 尾插
int list_insert_tail(NodePtr L, datatype e)
{// 判断逻辑if (NULL == L){printf("尾插插入失败\n");return -1;}// 找到最后一个节点NodePtr q = list_search_pos(L, L->len);// 封装节点NodePtr p = apply_node(e);// 插入逻辑p->next = q->next;q->next = p;L->len++;printf("尾插插入成功\n");return 0;
}//链表遍历
int list_show(NodePtr L)
{if (NULL == L || list_empty(L)){printf("遍历失败\n");return -1;}NodePtr q = L->next;while(q !=L){printf("%d\t",q->data);q = q->next;}putchar(10);printf("遍历成功\n");return 0;
}//头删
int list_delete_head(NodePtr L)
{if (NULL == L || list_empty(L)){printf("头删失败\n");return -1;}NodePtr p = L->next;L->next = p->next;free(p);p = NULL;L->len--;printf("头删成功\n");return 0;
}// 链表删除
void list_destroy(NodePtr L)
{if (NULL == L ){printf("删除失败\n");return;}while (L->next == L){list_delete_head(L);}free(L);L = NULL;printf("删除成功\n");return ;
}// 任意位置删除
int list_delete_pos(NodePtr L, int pos)
{if (NULL == L || pos > L->len + 1 || pos < 1){printf("删除失败\n");return -1;}NodePtr q = list_search_pos(L, pos - 1);NodePtr p = q->next;q->next = p->next;free(p);p = NULL;L->len--;printf("删除成功\n");return 0;
}
00main.c
#include "00.h"int main(int argc, char const *argv[])
{//创建列表NodePtr L = list_create();if (NULL == L){return -1;}//num 人数 die 死亡序号int num, die = 0;printf("输入参与约瑟夫游戏的人数:\n");scanf("%d", &num);printf("报数到多少被杀掉:\n");scanf("%d", &die);//为参与者赋予代号for (int i = 0; i < num; i++){list_insert_head(L, i+1);}list_show(L);//day 日期 all 总人数 death 死者数组int day = 0;int all = num;datatype death[100] = {0}; //死者序列NodePtr p = L;while (num>all/2){for (int i = 0; i < die-1; i++){if (p->next == L)//到头节点时多偏移一位,略过头节点{p = p->next;}p = p->next;}int kill = p->next->data; //死者代号death[day] = kill; //将死者代号存入死者名列printf("%d\n",kill);list_delete_head(p->next); //删除死者位置day++; //日期推移num--; //人数减一}printf("死者代号及顺序依次为:\n");for (int i = 0; i < day; i++){printf("%d\t", death[i]);}putchar(10);return 0;
}

双向循环链表
00.h
#ifndef day16_1_flag_h
#define day16_1_flag_h
#include <myhead.h>typedef char datatype;typedef struct Node
{union {int len;datatype data;};struct Node *next;struct Node *prio;}Node,*NodePtr;NodePtr list_create();int list_empty(NodePtr L);NodePtr apply_node(datatype e);NodePtr list_search_pos(NodePtr L,datatype pos);int list_insert_tail(NodePtr L,datatype e);int list_insert_head(NodePtr L,datatype e);int list_show(NodePtr L);int list_delete_head(NodePtr L);void list_destroy(NodePtr L);// 任意位置删除
int list_delete_pos(NodePtr L, int pos);//按位置取值
int list_pos_value(NodePtr L,int pos);//按位置修改
int list_change_pos(NodePtr L,int pos,datatype e);
#endif // day16_1_flag_h
00.c
#include "00.h"
#define MAX 50// 创建链表
NodePtr list_create()
{// 在堆区申请一个头节点NodePtr L = (NodePtr)malloc(sizeof(Node));if (NULL == L){printf("创建失败\n");return NULL;}L->len = 0;L->next = L; // 头节点指针域指向自己L->prio = L;printf("链表创建成功\n");return L;
}// 判空
int list_empty(NodePtr L)
{return L->next == L;
}// 申请封装数据
NodePtr apply_node(datatype e)
{NodePtr p = (NodePtr)malloc(sizeof(Node));if (NULL == p){printf("数据类型不合法,封装失败\n");return NULL;}p->data = e;p->next = NULL;p->prio = NULL;return p;
}// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{if (NULL == L || list_empty(L) || pos > L->len || pos < 0){printf("查找失败\n");return NULL;}NodePtr q = L;for (int i = 0; i < pos; i++){q = q->next;}printf("查找成功\n");return q;
}// 头插
int list_insert_head(NodePtr L, datatype e)
{if (NULL == L){printf("数据类型不合法,头插失败\n");return -1;}NodePtr p = apply_node(e);if (NULL == p){printf("数据封装失败,头插失败\n");return -1;}if (list_empty(L)){p->prio = L;p->next = L->next; // p->next = LL->next = p;L->prio = p;}else{p->prio = L;p->next = L->next;L->next->prio = p; // p->next->prio =p;L->next = p;}L->len++;printf("插入成功\n");return 0;
}// 尾插
int list_insert_tail(NodePtr L, datatype e)
{// 判断逻辑if (NULL == L){printf("尾插插入失败\n");return -1;}// 找到最后一个节点NodePtr q = list_search_pos(L, L->len);// 封装节点NodePtr p = apply_node(e);// 插入逻辑p->next = q->next;p->prio = q;q->next = p;L->len++;printf("尾插插入成功\n");return 0;
}// 链表遍历
int list_show(NodePtr L)
{if (NULL == L || list_empty(L)){printf("遍历失败\n");return -1;}NodePtr q = L->next;while (q != L){printf("%c", q->data);q = q->next;}putchar(10);printf("遍历成功\n");return 0;
}// 头删
int list_delete_head(NodePtr L)
{if (NULL == L || list_empty(L)){printf("头删失败\n");return -1;}NodePtr p = L->next;L->next = p->next;p->next->prio = L;free(p);p = NULL;L->len--;printf("头删成功\n");return 0;
}// 链表删除
void list_destroy(NodePtr L)
{if (NULL == L){printf("删除失败\n");return;}while (L->next == L){list_delete_head(L);}free(L);L = NULL;printf("删除成功\n");return;
}// 任意位置删除
int list_delete_pos(NodePtr L, int pos)
{if (NULL == L || pos > L->len + 1 || pos < 1){printf("删除失败\n");return -1;}NodePtr q = list_search_pos(L, pos - 1);NodePtr p = q->next;q->next = p->next;p->next->prio = q;free(p);p = NULL;// NodePtr p = L->next;// L->next = p->next;// p->next->prio = L;// free(p);// p = NULL;L->len--;printf("按位置删除成功\n");return 0;
}//按位置修改
int list_change_pos(NodePtr L,int pos,datatype e)
{if (NULL == L || pos > L->len + 1 || pos < 1){printf("修改失败\n");return -1;}NodePtr q = list_search_pos(L, pos);q->data = e;printf("按位置修改成功\n");return 0;
}
#include "00.h"int main(int argc, char const *argv[])
{NodePtr L = list_create();if (NULL == L ){return -1;}putchar(10);list_insert_head(L,'H');list_insert_head(L,'e');list_insert_head(L,'l');list_insert_head(L,'l');list_insert_head(L,'o');list_show(L);putchar(10);list_insert_tail(L,'Z');list_show(L);putchar(10);list_delete_head(L);list_show(L);putchar(10);list_delete_pos(L,3);list_show(L);putchar(10);list_change_pos(L,4,'A');list_show(L);putchar(10);list_destroy(L);list_show(L);putchar(10);return 0;
}
实现结果

相关文章:
学习记录day16—— 数据结构 双向链表 循环链表
双向链表 1、概念 1)就是从任意一个节点既能存储其前驱节点,又能存储后继节点 2)结构体中增加一个指向前驱节点的指针 //定义数据类型 typedef int datatype;//定义节点类型 typedef struct Node {union {int len;datatype data;};struct Node *prio; …...
Air780EP模块 AT开发-MQTT接入OneNET移动物联网平台应用指南
应用概述 使用AT方式通过MQTT协议连接onenet studio。官网地址:https://open.iot.10086.cn/ 材料准备 Air780EP(V)开发板一套,包括天线SIM卡,USB线。 PC电脑,串口工具 在onenet上创建产品 打开OneNET官网,进入控制…...
HOST处理器预读PCI设备
在PCI(Peripheral Component Interconnect)总线规范中,MRL(Memory Read Line)和MRM(Memory Read Multiple)是两种读取存储器地址空间的总线事务类型。 MRL(Memory Read Line…...
【Ansible】通过role角色部署lnmp架构
目录 一.roles概述 1.roles角色 2.roles的目录层次 2.1.roles 内各目录含义解释 二.实操 1.部署nginx 2.部署MySQL 3.部署php 4.编写测试文件 三.总结 一.roles概述 1.roles角色 可以把playbook剧本里的每个play看作为一个角色,将每个角色要用到的文件、…...
springboot给属性赋值的两种方式(yaml与properties)
一,介绍 在Spring Boot中,配置文件是用来设置应用程序的各种参数和操作模式的重要部分。Spring Boot支持两种主要类型的配置文件:properties文件和YAML 文件。这两种文件都可以用来定义相同的配置,但它们在格式和表达能力上有所不…...
20240725 每日AI必读资讯
🚀最强开源模型来了!Llama3.1以405B参数领先GPT-4o - Llama3.1以405B参数领先GPT-4o和Claude3.5Sonnet,在性能上实现超越。 - Meta大幅优化训练栈,扩展模型算力规模至16000个H100GPU,提高性能。 - Llama3.1具有上下文长度扩展、…...
17_高级进程间通信 UNIX域套接字1
非命名的UNIX域套接字 第1个参数domain,表示协议族,只能为AF_LOCAL或者AF_UNIX; 第2个参数type,表示类型,只能为0。 第3个参数protocol,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STR…...
大型语言模型的生物医学知识图优化提示生成
大型语言模型的生物医学知识图优化提示生成 https://arxiv.org/abs/2311.17330 https://github.com/BaranziniLab/KG_RAG 大型语言模型的生物医学知识图优化提示生成 摘要 KG-RAG框架,较好的结合了生物医学知识图谱SPOKE和LLM的优势。SPOKE是一个开放知识图谱&…...
winform datagrid 全部勾选
如果我们想要进行全选或全部取消,在数据较多的情况下,这种方法显然特别繁琐。怎么办呢? 当然是加以一个全选按钮了,选中全选按钮则全选,否则取消。笔者本想在红色圆圈位置添加全选复选框的,那样看起来更加…...
从 NextJS SSRF 漏洞看 Host 头滥用所带来的危害
前言 本篇博文主要内容是通过代码审计以及场景复现一个 NextJS 的安全漏洞(CVE-2024-34351)来讲述滥用 Host 头的危害。 严正声明:本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能…...
LC617-合并二叉树
文章目录 1 题目描述2 思路优化代码完整输入输出 参考 1 题目描述 https://leetcode.cn/problems/merge-two-binary-trees/description/ 给你两棵二叉树: root1 和 root2 。 将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另…...
深入解析:端到端目标检测模型的奥秘
深入解析:端到端目标检测模型的奥秘 在人工智能领域,计算机视觉任务一直是研究的热点之一。目标检测作为计算机视觉中的核心问题,其重要性不言而喻。端到端的目标检测模型,以其高效的性能和简洁的架构,逐渐成为研究和…...
xmind--如何快速将Excel表中多列数据,复制到XMind分成多级主题
每次要将表格中的数据分成多级时,只能复制粘贴吗 快来试试这个简易的方法吧 这个是原始的表格,分成了4级 步骤: 1、我们可以先按照这个层级设置下空列(后买你会用到这个空列) 二级不用加、三级前面加一列、四级前面加…...
在 Android 上实现语音命令识别:详细指南
在 Android 上实现语音命令识别:详细指南 语音命令识别在现代 Android 应用中变得越来越普遍。它允许用户通过自然语言与设备进行交互,从而提升用户体验。本文将详细介绍如何在 Android 上实现语音命令识别,包括基本实现、带有占位槽位的命令处理,以及相关的配置和调试步骤…...
怎么理解FPGA的查找表与CPLD的乘积项
怎么理解 fpga的查找表 与cpld的乘积项 FPGA(现场可编程门阵列)和CPLD(复杂可编程逻辑器件)是两种常见的数字逻辑器件,它们在内部架构和工作原理上有着一些显著的区别。理解FPGA的查找表(LUT,L…...
51.2T 800G 以太网交换机,赋能AI开放生态
IB与以太之争 以太网替代IB趋势明显。据相关报告:2024年TOP500的超算中,采用以太网方案占比48.5%,InfiniBand占比为39.2%,其中排名前6的超算中已有5个使用以太网互联。 开放系统战胜封闭系统仅是时间问题。我们已经看到…...
【制作100个unity游戏之31】用unity制作一个爬坡2d赛车小游戏
最终效果 【制作100个unity游戏之31】用unity制作一个爬坡2d赛车小游戏 前言 今天用unity制作一个简单的爬坡2d赛车小游戏 素材 https://www.spriters-resource.com/mobile/hillclimbracing/ 拼装车素材 车身添加碰撞体,摩檫力0 轮胎添加碰撞体和刚体࿰…...
Spring Boot 注解 @PostConstruct 介绍
Spring Boot 注解 PostConstruct 介绍 文章目录 Spring Boot 注解 PostConstruct 介绍一、基本介绍二、PostConstruct 的执行时机Spring Bean 的生命周期PostConstruct 的确切执行时机执行顺序示例重要注意事项 三、使用场景及代码示例1. 初始化资源:比如打开数据库…...
深度学习环境配置报错解决日记
2024年7越24日 1、detectron2需要编译 首先需要在自己创建的虚拟环境中下载一下detectron2 conda create -n pytorch python3.9 conda activate pythorch git clone https://github.com/facebookresearch/detectron2.git 接下来就是编译环节: 在win系统中&…...
百度,有道,谷歌翻译API
API翻译 百度,有道,谷歌API翻译(只针对中英相互翻译),其他语言翻译需要对应from,to的code 百度翻译 package fills.tools.translate; import java.util.ArrayList; import java.util.HashMap; import java.util.Lis…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
