顺序表功能实现(入手版详解)
🍉博客主页:阿博历练记
📖文章专栏:数据结构与算法
🚚代码仓库:阿博编程日记
🌹欢迎关注:欢迎友友们点赞收藏+关注哦

文章目录
- 🍓前言
- ✨顺序表
- 🔍1.顺序表的整体框架
- 🔍2.打印顺序表的菜单
- 🔍3.主函数的创建
- ⭐第一个case后面加中括号
- ⭐枚举变量和函数名同名
- 🔍4.顺序表的定义
- 🔍5.顺序表的初始化
- ⭐传结构体本身还是它的地址
- 🔍6.顺序表的尾插
- 🔍7.顺序表的打印
- 🔍8.顺序表的头插
- ⭐挪动数据(从后往前)
- 🔍9.顺序表的尾删
- ⭐assert的声明
- ⭐数组越界不一定报错
- 🔍10.顺序表的头删
- ⭐挪动数据(从前往后)
- 🔍11.顺序表任意位置的插入
- 🔍12.顺序表任意位置的删除
- ⭐assert声明的改变&&函数的附用
- 🔍13.顺序表数据的查找
- 🔍13.顺序表数据的修改
- 🔍14.顺序表的销毁
- 👻Seqlist.h代码
- 👻Seqlist.c代码
- 👻test.c代码
🍓前言
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
1.静态顺序表:使用定长数组存储元素.
2.动态顺序表:使用动态开辟的数组存储.
友友们,这里虽然顺序表删除需要挪动大量的元素很不方便,但是顺序表有个绝对的优势就是下标的随机访问,比如:二分查找、还有一些排序都需要作用到数组之上.
✨顺序表
🔍1.顺序表的整体框架
1.创建一个test.c文件:测试顺序表的相关功能
2.创建一个SeqList.c文件:实现顺序表功能的定义
3.创建一个SeqList.h文件:实现顺序表功能的声明
🔍2.打印顺序表的菜单
void menu()
{printf("***************************\n");printf("****1.尾插数据 2.尾删数据****\n");printf("****3.头插数据 4.头删数据****\n");printf("****5.打印数据 0.退出 ****\n");printf("***************************\n");
}
🔍3.主函数的创建
enum option
{ Destory,PushBack,PopBack,PushFront,PopFront,Print,
};
int main()
{SL s;SLInit(&s);int option = 0;do{menu();printf("请输入你的选择:\n");scanf("%d", &option);switch (option){case PushBack:{printf("请输入要尾插数据的个数,再依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushBack(&s, x);n--;}break;}case PopBack:printf("尾删成功\n");SLPopBack(&s);break;case PushFront:printf("请输入要头插数据的个数,在依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushFront(&s, x);n--;}break;case PopFront:printf("头删成功\n");SLPopFront(&s);break;case Print:SLPrint(&s);break;case Destory:SLDestory(&s);break;default:printf("选择错误,请重新选择:\n");break;}} while (option);return 0;
}
⭐第一个case后面加中括号
友友们,这里我们加中括号是因为我们需要把它里面的n和x变成
局部变量,防止和下面的x和n出现变量的重定义
⭐枚举变量和函数名同名
函数名代表函数的地址,可以认为是函数指针类型,如果我们用它当作枚举变量的话,这里我们就会改变它的类型,当再次调用函数的时候,程序就会报错.

🔍4.顺序表的定义
//typedef int SLDatatype;
//
//struct Seqlist
//{
// SLDatatype a[N]; //静态的顺序表 给小了不够用,给大了浪费,这里我们考虑动态顺序表
// int size;
//};typedef int SLDatatype;typedef struct Seqlist
{SLDatatype * a; //动态的顺序表int size; //存储的有效数据个数int capcity; //容量空间
}SL;
🔍5.顺序表的初始化
void SLInit(SL* ps1)
{assert(ps1);ps1->a =(SLDatatype*)malloc(sizeof(SLDatatype)*4);if (ps1->a == NULL){perror("malloc");return;}ps1->capcity = 4;ps1->size = 0;
}
⭐传结构体本身还是它的地址
1.传结构体本身

2.传结构体的地址

友友们,这里传结构体本身,形参相当于实参的一份
临时拷贝,形参的改变不会影响实参,所以如果如果我们要改变它,就要传它的地址,这样我们解引用就可以改变它了.
🔍6.顺序表的尾插
void SLCheckcapcity(SL*ps1)
{assert(ps1);if (ps1->size == ps1->capcity){SLDatatype* temp =(SLDatatype*) realloc(ps1->a, sizeof(SLDatatype) * ps1->capcity * 2); if (temp == NULL){perror("realloc");return;}ps1->a = temp;ps1->capcity *= 2;}
}
void SLPushBack(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);ps1->a[ps1->size++] = x;
}


🔍7.顺序表的打印
void SLPrint(SL* ps1)
{assert(ps1);for (int i = 0; i < ps1->size; i++){printf("%d ", ps1->a[i]);}printf("\n");
}
🔍8.顺序表的头插
1.方法一:
void SLPushFront(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);//挪动数据int end = ps1->size - 1;while (end >= 0){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[0] = x;ps1->size++;
}
⭐挪动数据(从后往前)

2.方法二:
void SLPushFront(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);//挪动数据int end = ps1->size;while (end > 0){ps1->a[end] = ps1->a[end-1];end--;}ps1->a[0] = x;ps1->size++;
}
🔍9.顺序表的尾删
void SLPopBack(SL* ps1)
{assert(ps1->size > 0&&ps1); //暴力检查ps1->size--;
}

⭐assert的声明
友友们注意,如果我们顺序表里面有5个数据,而我们尾删6次,这时候ps1->size就变成-1了,就会出现数组越界,就是第一个数据放到下标为-1的位置上了,导致结果出错. 所以这里我们就需要assert来声明一下:如果顺序表为空,就不需要再尾删了.

⭐数组越界不一定报错
友友们一定要清楚越界本身就是一个抽查,并不是一定会报错的,如果数组下标越界了,那么它会自动接着那块内存往后写,如果界外的空间暂时没有被利用,那么我们就可以占用那块内存,但是如果界外的内存已经存放了数据,我们越界过去就会覆盖那块内存,则就有可能导致错误的产生.
🔍10.顺序表的头删
1.方法一:start为1
void SLPopFront(SL* ps1)
{assert(ps1);assert(ps1->size > 0);int start = 1;while (start < ps1->size){ps1->a[start - 1] = ps1->a[start];start++;}ps1->size--;
}
2.方法二:start为0
void SLPopFront(SL* ps1)
{assert(ps1);assert(ps1->size > 0);int start = 0;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
⭐挪动数据(从前往后)

🔍11.顺序表任意位置的插入
void SLInsert(SL* ps1, int pos,SLDatatype x)
{assert(pos >= 0 && pos <= ps1->size&&ps1); //防止越界访问SLCheckcapcity(ps1);int end = ps1->size - 1;while (end >= pos){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[pos] = x;ps1->size++;
}

友友们,这里我们的
头插和尾插其实就是两种特殊位置的任意插入,这时候我们就可以附用这个函数,比如头插:SLInsert(ps1,0,x),尾插:SLInsert(ps1,ps1->size,x).
🔍12.顺序表任意位置的删除
1.方法一:start为pos+1
void SLErase(SL* ps1, int pos)
{assert(pos >= 0 && pos < ps1->size&&ps1); //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素int start = pos + 1;while (start < ps1->size){ps1->a[start - 1] = ps1->a[start];start++;}ps1->size--;
}
2.方法二:start为pos
void SLErase(SL* ps1, int pos)
{assert(pos >= 0 && pos < ps1->size&&ps1); //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素int start = pos;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
⭐assert声明的改变&&函数的附用
友友们注意,这里pos就不能等于ps1->size了,因为我们要删除顺序表中的数据,它最多下标为ps1->size-1.这里我们的
头删和尾删就可以附用这个函数,头删就是:SLErase(ps1,0),尾删就是:(ps1,ps1->size-1).
🔍13.顺序表数据的查找
int SLFind(SL* ps1, SLDatatype x)
{assert(ps1);for (int i = 0; i < ps1->size; i++){if (ps1->a[i] == x){return i;}}return -1;
}
友友们注意,因为下标不可能是负数,所以我们没有找到就可以返回负数,一般我们都使用-1.
🔍13.顺序表数据的修改
void Modify(SL* ps1, int pos, SLDatatype x)
{assert(pos >= 0 && pos < ps1->size&&ps1);ps1->a[pos] = x;
}
🔍14.顺序表的销毁
1.free之后需要置空
void SLDestory(SL*ps1)
{assert(ps1);free(ps1->a);ps1->a = NULL;ps1->size = 0;ps1->capcity = 0;
}
友友们,这里我们把ps1->a释放之后,因为它不是在函数内部创建的指针变量,它存放的是顺序表的地址,所以释放之后,函数外部可能会调用到它,所以我们这里需要及时置空.
2.free之后不需要置空
void rate(int* nums, int numsSize, int k)
{if (k > numsSize){k %= numsSize;}int* temp = (int*)malloc(sizeof(int) * numsSize);memcpy(temp + k, nums, sizeof(int) * numsSize - k);memcpy(temp, nums + numsSize - k, sizeof(int) * k);memcpy(nums, temp, sizeof(int) * numsSize);free(temp);temp = NULL;
}
友友们注意了,这里的temp是我们在这个函数内部创建的指针变量,它是一个局部变量,它出完函数作用域就销毁了,所以我们free释放之后,就还给操作系统了,以后它也不会被调用了,所以这里我们不置空也是可以的.
👻Seqlist.h代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//typedef int SLDatatype;
//
//struct Seqlist
//{
// SLDatatype a[N]; //静态的顺序表 给小了不够用,给大了浪费,这里我们考虑动态顺序表
// int size;
//};typedef int SLDatatype;typedef struct Seqlist
{SLDatatype * a; //动态的顺序表int size; //存储的有效数据个数int capcity; //容量空间
}SL;
void SLInit(SL* ps1);
void SLDestory(SL *ps1);
void SLPushBack(SL* ps1, SLDatatype x);
void SLPushFront(SL* ps1, SLDatatype x);
void SLPopBack(SL* ps1);
void SLPopFront(SL* ps1);
void SLPrint(SL* ps1);
void SLInsert(SL* ps1, int pos,SLDatatype x);
void SLErase(SL* ps1, int pos);
//找到了返回下标,找不到返回-1
int SLFind(SL* ps1, SLDatatype x);
void Modify(SL* ps1, int pos, SLDatatype x);
👻Seqlist.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void SLInit(SL* ps1)
{assert(ps1);ps1->a =(SLDatatype*)malloc(sizeof(SLDatatype)*4);if (ps1->a == NULL){perror("malloc");return;}ps1->capcity = 4;ps1->size = 0;
}
void SLDestory(SL*ps1)
{assert(ps1);free(ps1->a);ps1->a = NULL;ps1->size = 0;ps1->capcity = 0;
}
void SLPrint(SL* ps1)
{assert(ps1);for (int i = 0; i < ps1->size; i++){printf("%d ", ps1->a[i]);}printf("\n");
}
void SLCheckcapcity(SL*ps1)
{assert(ps1);if (ps1->size == ps1->capcity){SLDatatype* temp =(SLDatatype*) realloc(ps1->a, sizeof(SLDatatype) * ps1->capcity * 2); if (temp == NULL){perror("realloc");return;}ps1->a = temp;ps1->capcity *= 2;}
}
void SLPushBack(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);ps1->a[ps1->size++] = x;
}
void SLPushFront(SL* ps1, SLDatatype x)
{assert(ps1);SLCheckcapcity(ps1);//挪动数据int end = ps1->size;while (end >0){ps1->a[end] = ps1->a[end-1];end--;}ps1->a[0] = x;ps1->size++;/*assert(ps1);SLInsert(ps1, 0, x);*/
}
void SLPopBack(SL* ps1)
{assert(ps1->size > 0&&ps1); //暴力检查/*ps1->a[ps1->size - 1] = 0;*/ //有可能最后一个数据就是0/*if (ps1->size == 0) {return;}*/ps1->size--;/*assert(ps1);SLErase(ps1, ps1->size - 1);*/
}
void SLPopFront(SL* ps1)
{assert(ps1);assert(ps1->size > 0);int start = 0;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
void SLInsert(SL* ps1, int pos,SLDatatype x)
{assert(pos >= 0 && pos <= ps1->size&&ps1); //防止越界访问SLCheckcapcity(ps1);int end = ps1->size - 1;while (end >= pos){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[pos] = x;ps1->size++;
}
void SLErase(SL* ps1, int pos)
{assert(pos >= 0 && pos < ps1->size&&ps1); //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素int start = pos;while (start < ps1->size-1){ps1->a[start] = ps1->a[start+1];start++;}ps1->size--;
}
int SLFind(SL* ps1, SLDatatype x)
{assert(ps1);for (int i = 0; i < ps1->size; i++){if (ps1->a[i] == x){return i;}}return -1;
}
void Modify(SL* ps1, int pos, SLDatatype x)
{assert(pos >= 0 && pos < ps1->size&&ps1);ps1->a[pos] = x;
}
👻test.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void menu()
{printf("***************************\n");printf("****1.尾插数据 2.尾删数据****\n");printf("****3.头插数据 4.头删数据****\n");printf("****5.打印数据 0.退出 ****\n");printf("***************************\n");
}
enum option
{ Destory,PushBack,PopBack,PushFront,PopFront,Print,
};
int main()
{SL s;SLInit(&s);int option = 0;do{menu();printf("请输入你的选择:\n");scanf("%d", &option);switch (option){case PushBack:{printf("请输入要尾插数据的个数,再依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushBack(&s, x);n--;}break;}case PopBack:printf("尾删成功\n");SLPopBack(&s);break;case PushFront:printf("请输入要头插数据的个数,在依次输入要插入的数据:\n");int n = 0;scanf("%d", &n);int x = 0;while (n > 0){scanf("%d", &x);SLPushFront(&s, x);n--;}break;case PopFront:printf("头删成功\n");SLPopFront(&s);break;case Print:SLPrint(&s);break;case Destory:SLDestory(&s);break;default:printf("选择错误,请重新选择:\n");break;}} while (option);return 0;
}
相关文章:
顺序表功能实现(入手版详解)
🍉博客主页:阿博历练记 📖文章专栏:数据结构与算法 🚚代码仓库:阿博编程日记 🌹欢迎关注:欢迎友友们点赞收藏关注哦 文章目录 🍓前言✨顺序表🔍1.顺序表的整体…...
Java 中的线程是什么,如何创建和管理线程-下(十三)
书接上文 CompletableFuture CompletableFuture 是 Java 8 中新增的类,提供了更为强大的异步编程支持。它可以将多个异步任务组合成一个整体,并且可以处理异常情况。 例如,可以使用 CompletableFuture 来实现异步任务的串行执行࿱…...
为什么我的Windows 10 便签不支持更改字体?
Windows便签是一款常用的记录工具,可以帮助我们快速记录一些重要的信息。在使用Windows便签时,如果你想要更好地呈现你的信息,可以通过设置字体来达到这个效果。本文将介绍Windows便签字体设置的相关知识,希望对你有所帮助。 1、打…...
野火STM32电机系列(六)Cubemx配置ADC规则和注入通道
前文已经配置了GPIO、编码器 本节讲解CubeMXADC规则和注入通道 本文adc注入通道采用定时器触发,因此在上文定时器配置的基础上进行 常规信号(温度等)使用带DMA的常规通道连续采样 注入采样由定时器触发,采集电机三相电流&…...
预制菜,巨头们的新赛场
俗话说“民以食为天”,饮食对于大众的重要性自然是无需赘述。然而,随着生活节奏的加快,越来越多年轻人没有时间和精力去烹制菜肴,这也是外卖行业持续火热的重要原因之一。尽管如此,随着消费者健康意识的持续提升&#…...
英语语法第一章之英语语法综述
英语的任何句型基本都可以翻译成 什么怎么样 ,在这里什么就是我们常说的主语,而怎么样就是我们常说的谓语; 可能有些小伙伴会反问,不是主谓宾吗?别急等我慢慢讲解 在这里谓语也有很有多的不同的动作 可以独立完成的动作 句型&am…...
ChatGPT被淘汰了?Auto-GPT到底有多强
大家好,我是可夫小子,关注AIGC、读书和自媒体。解锁更多ChatGPT、AI绘画玩法。 说Auto-GPT淘汰了ChatGPT了,显然是营销文案里面的标题党。毕竟它还是基于ChatGPT的API,某种意义只是基于ChatGPT能力的应用。但最近,Auto…...
unity NGUI使用方法
基本用法 很多基本模块比如按钮、slider等都能从Prefab中直接拖拽到场景中实现,但都需要有一个Collider(Prefab已经自带) 因为不仅是UI,所有带有Collider的游戏物体都能接收到OnClick, OnPress这样的事件——前提是需…...
软件测试技术(五)软件测试流程
软件测试流程 软件测试流程如下: 测试计划测试设计测试执行 单元测试集成测试确认测试系统测试验收测试回归测试验证活动 测试计划 测试计划由测试负责人来编写,用于确定各个测试阶段的目标和策略。这个过程将输出测试计划,明确要完成的测…...
Redis缓存穿透和雪崩
Redis缓存穿透和雪崩 Redis缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题…...
【C++】set和map的使用
对于STL容器来说,有很多相似的功能,所以这里主要将与之前不同的功能说清楚 文章目录 1.对于set与map的简单理解2. setinsert迭代器遍历countmultisetinsertfindcount 3. mapinsert与迭代器的使用统计水果次数 operator []operator[]的实现理解对整体的拆…...
大学生学java编程的就业前景怎么样?我来聊聊自己的见解
今天兴哥想跟大家分享一个话题,就是学java到底好不好找工作。因为我发现很多粉丝朋友,之前可能并不是从事IT行业的,然后想转行来做这一行,或者是有些大四即将面临毕业的老哥,可能大学没有好好学习吧,然后专…...
JavaScript全解析——canvas 入门(上)
●canvas 是 HTML5 新增的一个标签, 表示画布 ●canvas 也是 h5 的画布技术, 我们通过代码的方式在画布上描绘一个图像 canvas 标签 ●向进行 canvas 绘图, 首先我们先要了解到 canvas 标签 ●是 html5 推出的一个标签 <html> <head>... </head> <body&…...
vue 插槽的用法
Vue的插槽(Slot)是一种可以让父组件向子组件传递内容的机制。插槽可以让开发者将组件的结构和内容分离开来,从而实现更好的可维护性和复用性。 在Vue中,插槽通过 标签实现。具体用法如下: 单个插槽 在子组件中使用一…...
【C++复习2】C++编译器的工作原理
如果你是一名newbird的话,建议观看如下视频加深你的理解,再看如下内容: https://www.bilibili.com/video/BV1N24y1B7nQ?p7 The cherno会额外告诉你如何将目标文件转换成汇编代码,CPU执行指令的过程以及编译器如何通过删除冗余变…...
回调函数_回顾
函数指针和回调函数 函数指针是指向函数的指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。 函数指针可以像一般函数一样,用于调用函数、传递参数。 直接用指针表示函数,而不是*指针ÿ…...
今天面了个字节跳动拿35K出来的,真是砂纸擦屁股,给我露了一手啊
今年的金三银四已经结束,很多小伙伴收获不错,拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文,为此咱这里也统一做一次大整理和大归类,这也算是划重点了。 俗话说得好,他山之…...
8. 数据结构与算法
8. 数据结构与算法 常见面试题 说说一个算法有哪些时间复杂度?归并算法时间复杂度是多少?⭐⭐⭐ O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) 归并算法时间复杂度是O(nlogn) 说说数组时间复杂度,什么场景下使用?⭐⭐⭐⭐⭐ 从渐进趋势…...
Springboot +Flowable,任务认领和回退(一)
一.简介 有的时候,一个任务节点会存在多个候选人,例如:张三提交一个任务,这个任务即可以由李四处理,又可以由王五处理,那么针对这种多个任务候选人的情况,该如何处理? 二.绘制流程…...
机器学习 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络模型答疑
机器学习 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络模型答疑 目录 机器学习 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络模型答疑问题汇总问题一答疑问题二答疑问题三答疑问题四答疑问题五答疑参考资料问题汇总 有几个问题咨询一下: 1.数据集划分时出现了问题如何解决? 2…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
LangChain【6】之输出解析器:结构化LLM响应的关键工具
文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器?1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...
CppCon 2015 学习:REFLECTION TECHNIQUES IN C++
关于 Reflection(反射) 这个概念,总结一下: Reflection(反射)是什么? 反射是对类型的自我检查能力(Introspection) 可以查看类的成员变量、成员函数等信息。反射允许枚…...

