一起学数据结构(2)——线性表及线性表顺序实现
目录
1. 什么是数据结构:
1.1 数据结构的研究内容:
1.2 数据结构的基本概念:
1.2.1 逻辑结构:
1.2.2 存储结构:
2. 线性表:
2.1 线性表的基本定义:
2.2 线性表的运用:
3 .线性表的顺序表示及实现(顺序表):
3.1 顺序表的概念及结构:
3.2 顺序表的代码实现:
3.2.1 顺序表的创建、初始化及销毁:
3.3 顺序表的四个特殊操作(头插、头删、尾插、尾删):
3.3.1 尾插:
3.3.2 尾删:
3.3.3 头插:
3.3.4 头删:
3.4 对顺序表的随机位置进行增删操作:
3.4.1 对顺序表的随机位置进行添加数据的操作:
3.4.2 对顺序表的随机位置进行删除数据的操作:
4. 代码总览:
4.1 头文件Seqlist.h:
4.2 函数功能实现文件 Seqlist.c
4.3 测试函数功能文件 test.c:
上一篇文章中,对数据结构中用于评判算法的两个标准,即:时间复杂度、空间复杂度进行简单的介绍及解释。本篇文章,会对:什么是数据结构?数据结构的基本概念进行简单的介绍。着重介绍线性表和线性表的顺序实现。
1. 什么是数据结构:
1.1 数据结构的研究内容:
计算机主要是被用于进行数值计算,这个过程可以分为以下几步:
1.从具体问题中抽象出数学模型。
2.设计相应的算法
3.对程序进行测试,调试等。
对于第一个步骤,也可以分为:分析问题、提取操作对象、找出操作对象之间的关系、用数学语言进行表述这四步。对于提取操作对象和找出操作对象之间的关系这两步,就是数据结构研究的主要内容
1.2 数据结构的基本概念:
首先给出数据结构的定义:
数据结构是相互之间一种或多种特定关系的数据元素的集合。或者说:数据结构是带“结构”的数据元素的集合,"结构“就是指数据元素之间存在的关系。对于数据结构,包含了逻辑结构和存储结构两个层次。
(注:本文只是对数据类型进行简单的介绍,所以,对于下面逻辑结构和存储结构,只给出概念与分类,其中包含的具体内容将会在后续的文章中进行介绍)
1.2.1 逻辑结构:
数据的逻辑结构是指从逻辑关系上描述数据 ,它与数据的存储无关,是独立于计算机的。数据结构的类型如下图所示:
1.2.2 存储结构:
数据对象在计算机中的存储表示称为数据的存储结构,也成为物理结构。数据元素在计算机中有两种基本的存储结构,分别是顺序存储结构和链式存储结构:
2. 线性表:
2.1 线性表的基本定义:
对于线性表,一个很典型的例子就是26英文字母的字母表:
从字母表中可以看出看出线性表的一些性质,例如:虽然线性表中的数据并不相同,但是同一线性表中的元素必定具有相同的特性,即属于同一数据对象。线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
2.2 线性表的运用:
对于线性表的运用,文章给出两个例子:
例1:一元多项式的运算:
在数学中,一个一元多项通常可以写成下面的形式:
在对一元多项式进行运算之前,首先要知道如何在计算机表示一元多项式。表示一元多项式,便是线性表的一个应用。
通过观察一元多项式可以发现:一元多项式的系数下标,与的指数相同。因此,可以用线性表来存储一元多项式中各项系数,即:
这时,对于一元多项式中各项中,的指数便隐藏在各项的系数下标中。
此时,假设还有一个一元多项式,运算
与
这两个一元多项式的和,便可以通过上面的思想,用线性表来表示各项系数之和,即:
例子2:稀疏多项式的表示:
给定一个稀疏多项式:
对于稀疏多项式,如果再采用上面存储多项式中各项系数的方法,则需要开辟个空间,但是上面的多项式,一共只有
个非零元素,所以,采用上面介绍的存储方法,会造成存储空间的极大浪费。
对于稀疏多项式的存储方法,应该存储每一项的系数和指数。如果把稀疏多项式改写成一元多项式的形式,即:
运用线性表对每一项的系数和指数保存,即:
由于本文主要是通过例子来介绍线性表,所以对于稀疏多项式的运算,文章不展开介绍,只给出运算方法及大体的运算规则:
假设由两个稀疏多项式、
。对两式进行相加时,需要先创建一个新的数组,假设为C,在运算时,遵从以下规则:
分别从头遍历并且比较两个稀疏多项式,对于相同的项,则两项系数相加,若系数之和不为
,则在数组C中记录相加项的系数
,对于
不同的项,则先将
较小的项添加到C中。
3 .线性表的顺序表示及实现(顺序表):
3.1 顺序表的概念及结构:
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。这种表示也称作线性表的顺序存储结构或顺序映像。特点是:逻辑上相邻的元素,其物理此些许也是相邻的,并且在顺序表中,任一元素都可以随机存取。即:
3.2 顺序表的代码实现:
3.2.1 顺序表的创建、初始化及销毁:
顺序表可以分为两种,分别是:静态顺序表、动态顺序表,对于静态顺序表,其代码表示为:
#define N 100
typedef int SLDataType;
struct Seqlist
{SLDataType arr[N]; //定长数组int size; //有效数据个数
}Seqlist;
对于静态顺序表,有一个极大的缺陷,便是内存大小使用不够灵活。比如上面给出的代码,如果需要存储的数据的个数只有几个,则会造成极大的内存空间浪费,如果需要存储的数据的个数大于100,则超出了数组的最大存储范围。所以,为了解决上述问题,在创建顺序表时,一般创建对于内存使用更加灵活的动态顺序表,代码如下:
typedef int SLDataType;typedef struct Seqlist
{SLDataType* a; //动态开辟数组的方式,a表示数组首元素地址size_t size; //数组中有效的数据个数size_t capacity; //容量大小
}SL;
使用动态顺序表后,对于内存空间的使用便灵活很多,例如,编写一个内存空间检查函数,每次向顺序表中添加数据元素时,先通过内存空间检查函数进行检查,当内存空间不够用时,可以通过动态内存管理函数对已有的内存空间进行增容。
对于顺序表的初始化,将顺序表初始化函数命名为,函数内容如下:
void SLInit(SL* ps)
{ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
上面的代码只是给了初始化函数的大体框架,在实际使用中,并不会把顺序表中的三项内容全都初始化为,而是在初始化时,开辟一定的空间。例如在初始化时,给予
字节大小的空间:
void SLInit(SL* ps)
{ps->a =(SLDataType*)malloc(sizeof(SLDataType)*4);if (ps->a == NULL){perror("malloc");exit (-1);}ps->size = 0;ps->capacity = 4;
}
其中的是动态内存管理函数的一种,对于动态内存管理函数的使用,可以参考下面给出的文章链接中的内容C语言——动态内存管理:_爱写代码的粉毛护理的博客-CSDN博客
语句用于判断是否成功的开辟了空间。
对于动态顺序表的销毁,直接使用函数对动态开辟的空间进行释放即可。代码如下:
void SLDestroy(SL* ps)
{free(ps);ps->a = NULL;ps->size = ps->capacity = 0;
}
3.3 顺序表的四个特殊操作(头插、头删、尾插、尾删):
3.3.1 尾插:
给出一个顺序表,其中的数组中存储的元素如图所示:
由上面对于顺序表的定义可知:
capacity表示顺序表的数组的容量大小
a表示数组,后面的数字表示这个数组中存储的元素
size表示数组中存储元素的个数
size-1用来表示数组下标
对上述数组进行尾插操作,假设第一次插入数字,则:
进行尾插后,令用来表示数组中存储元素个数的变量
此时,再进行一次尾插,插入数字,则:
进行尾插后,同样令用来表示数组中存储元素格式的变量; 此时,
。表示顺序表中的数组的空间已经被占满,如果还需要进行尾插操作,则需要对数组的空间进行扩容。因为,为了避免上面的情况发生,应该在每次进行尾插操作之前,都对顺序表进行一次检查,如果,则对数组的空间进行扩容,对于扩容空间的大小,一般扩为原来空间的
倍,代码如下:
void SLPushBack(SL* ps, SLDataType x)
{if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));if(tmp == NULL){perror("realloc");}ps->a = tmp;ps->capacity = ps->capacity * 2;}ps->a[ps->size] = x;ps->size++;
}
对于上面给出的尾插代码,最核心的部分就是对内存空间进行扩容,即:
SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));
对于理解用于扩容的代码,需要将内存空间和的概念分清,
只是代表了已经开辟的内存空间的个数,不会反应内存空间的大小,因此,在上面用于扩容的代码中,
只是表示将内存空间的数量扩大到
倍,想到达到对内存空间的大小扩容到
倍,需要再乘上存储的数据的类型,即
(注:对于用于扩容的函数,也可以在下面给出的文章中进行了解C语言——动态内存管理:_爱写代码的粉毛护理的博客-CSDN博客)
如果已经掌握了对动态内存管理函数的初步使用,会发现,尾插的代码中,再对内存空间进行扩容后,并没有用函数去释放内存空间。这是因为
函数的返回值的特殊性质。这个性质同样也可以在上面给出的文章链接中进行了解,在本文中会进行简要的解释:
上面提到的函数的返回值的特殊性质,即:原地扩容、异地扩容。
对于原地扩容,如果对内存进行扩容时,后面有足够多的内存空间可以达到对已有内存空间进行扩容的目的,则函数返回值返回已有空间的首地址。
对于异地扩容,如果对内存进行扩容时,后面没有足够多的内存空间可以达到对已有内存空间进行扩容的目的,则函数会寻找一个新的空间,这个空间的地址是随机的,并且返回值返回这个新空间的首地址。这两个性质,可以由下面的代码进行演示:
int main()
{int* p1 = (int*)malloc(12);int* p2 = (int*)realloc(p1, 2);printf("%p %p\n",p1, p2);int* p3 = (int*)malloc(10);int* p4 = (int*)realloc(p3, 200);printf("%p %p",p3, p4);return 0;
}
结果如下:
可以验证,的地址表示,此时是原地扩。
此时,地址不同,是异地扩。
所以,函数对于扩容时不同情况的处理很灵活,不需要在扩容后用
函数释放内存空间。为了测试尾插的功能是否正常,封装一个函数,插入
这几个数字:
void test1()
{SL s1;SLInit(&s1);SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);SLPushBack(&s1, 6);SLPrint(&s1);
}
结果如下:
3.3.2 尾删:
尾删就是从末尾向前删除元素,原理比较简单,只需要让即可
//尾删:
void SLPopBack(SL* ps)
{ps->size--;
}
利用下面的代码测试尾删的功能:
void test1()
{SL s1;SLInit(&s1);SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);SLPushBack(&s1, 6);SLPopBack(&s1); SLPopBack(&s1);SLPrint(&s1);
}
结果如下:
3.3.3 头插:
在执行尾插操作时说到,每次插入前,需要检查以下数组的内存空间是否足够。在头插中,同样需要对内存空间进行检查,所以,为了方便操作,不如将尾插中用于检查数组内存空间的代码封装成一个函数。
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));if (tmp == NULL){perror("realloc");}ps->a = tmp;ps->capacity = ps->capacity * 2;}
}
对于头插,只需要将已有的元素全部向后移动一位,再把想要插入的元素插入到数组的首个位置。此时,因为插入了一个元素,所以,顺序表中的+1例如,头插一个数字
,可以用图表示为:
原数组:
全部元素向后挪动一位:
头插数字 :
将上述过程用代码表示:
void SLPushFront(SL* ps, SLDataType x)
{SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end+1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}
用下列函数对头插功能进行设置:
void test2()
{SL s2;SLInit(&s2);SLPushBack(&s2, 1);SLPushBack(&s2, 2);SLPushBack(&s2, 3);SLPushBack(&s2, 4);SLPushBack(&s2, 5);SLPushFront(&s2, 6);SLPrint(&s2);
}
结果如下:
(注:第一行的是测试尾插的结果,头插的结果是第一行)
3.3.4 头删:
头删的过程与头插相反,进行头插的操作时,需要把元素整体向后移动,且移动的顺序是从后向前,对于头删,则是需要从前向后一次覆盖前面的数据。
void SLPopFront(SL* ps)
{if (ps->size == 0){return;}int start = 0;int end = ps->size - 1;while (start <= end){ps->a[start] = ps->a[start+1];start++;}ps->size--;
}
用下面的函数测试头删的功能:
void test3()
{SL s3;SLInit(&s3);SLPushBack(&s3, 1);SLPushBack(&s3, 2);SLPushBack(&s3, 3);SLPushBack(&s3, 4);SLPushBack(&s3, 5);SLPopFront(&s3);printf("头删:");SLPrint(&s3);
}
结果如下:
3.4 对顺序表的随机位置
进行增删操作:
3.4.1 对顺序表的随机位置
进行添加数据的操作:
对随机位置添加数据的操作,与头插的操作流程相似。基本可以分为以下几步:
1.判断这个位置对于数组下标而言是否合法,即
2.将位置以及后面的元素整体后移动一位。
3.将新的元素插入到数组中下标为的位置
4.将
用图来表示上述过程,及:
将位置以及后续元素向后移动一位:
最后,向位置为的地方插入元素即可。因为多插入了一个元素,最后需要
代码如下:
void SLInsert(SL* ps, size_t i, SLDataType x)
{if (i < 0 || i >(ps->size - 1)){printf("坐标非法");exit(-1);}size_t end = ps->size - 1;for (size_t end = ps->size - 1; end > i-1; end--){ps->a[end + 1] = ps->a[end];}ps->a[i - 1] = x;ps->size++;
}
用下面的代码验证随机位置插入功能是否正常:
void test4()
{SL s4;SLInit(&s4);SLPushBack(&s4, 1);SLPushBack(&s4, 2);SLPushBack(&s4, 3);SLPushBack(&s4, 4);SLPushBack(&s4, 5);SLInsert(&s4, 3, 6);SLPrint(&s4);}
结果如下:
(注:结果是最后一行数字所展示的效果)
3.4.2 对顺序表的随机位置进行删除数据的操作:
对于在顺序表的随机位置删除数据的操作可以分为以下几步:
1.检查位置对于数组下标是否合理,即
2.将位置后面的元素整体向前移动一位。
3. 因为删除了一个元素,所以
将上述过程用图进行表示:
将位置后面的元素整体向前移动一位:
最后
将上述过程用代码表示:
void SLErase(SL* ps, size_t i)
{if (i <= 0 || (i > ps->size - 1)){printf("坐标非法");}size_t start = i-1;while (start <= ps->size - 1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}
用下面的函数测试功能:
void test5()
{SL s5;SLInit(&s5);SLPushBack(&s5, 1);SLPushBack(&s5, 2);SLPushBack(&s5, 3);SLPushBack(&s5, 4);SLPushBack(&s5, 5);SLErase(&s5, 3);SLPrint(&s5);}
结果如下:
(注:最后一行的数字对应着测试的功能的结果)
4. 代码总览:
4.1 头文件Seqlist.h:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>//#define N 100
//typedef int SLDataType;
//struct Seqlist
//{
// SLDataType arr[N];
// int size;
//}Seqlist;typedef int SLDataType;
typedef struct Seqlist
{SLDataType* a;size_t size;size_t capacity;
}SL;//用于打印测试:
void SLPrint(SL* ps);
//用于初始化顺序表
void SLInit(SL* ps);//用于销毁顺序表:
void SLDestroy(SL* ps);//尾插:
void SLPushBack(SL* ps, SLDataType x);//尾删
void SLPopBack(SL* ps);//检测内存空间
void SLCheckCapacity(SL* ps);//头插
void SLPushFront(SL* ps, SLDataType x);//头删
void SLPopFront(SL* ps);//随机位置插入
void SLInsert(SL* ps,size_t i ,SLDataType x);//随机位置删除
void SLErase(SL* ps, size_t i);
4.2 函数功能实现文件 Seqlist.c
#include"Seqlist.h"//初始化顺序表
void SLInit(SL* ps)
{ps->a =(SLDataType*)malloc(sizeof(SLDataType)*4);if (ps->a == NULL){perror("malloc");exit (-1);}ps->size = 0;ps->capacity = 4;
}//销毁顺序表void SLDestroy(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}//尾插:
void SLPushBack(SL* ps, SLDataType x)
{SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}//用于打印数据
void SLPrint(SL* ps)
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//尾删:
void SLPopBack(SL* ps)
{ps->size--;
}//检查内存空间:
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));if (tmp == NULL){perror("realloc");}ps->a = tmp;ps->capacity = ps->capacity * 2;}
}//头插
void SLPushFront(SL* ps, SLDataType x)
{SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end+1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}//头删:
void SLPopFront(SL* ps)
{if (ps->size == 0){return;}int start = 0;int end = ps->size - 1;while (start <= end){ps->a[start] = ps->a[start+1];start++;}ps->size--;
}//随机位置插入:
void SLInsert(SL* ps, size_t i, SLDataType x)
{if (i < 0 || i >(ps->size - 1)){printf("坐标非法");exit(-1);}size_t end = ps->size - 1;for (size_t end = ps->size - 1; end > i-1; end--){ps->a[end + 1] = ps->a[end];}ps->a[i - 1] = x;ps->size++;
}//随机位置删除:
void SLErase(SL* ps, size_t i)
{if (i <= 0 || (i > ps->size - 1)){printf("坐标非法");}size_t start = i-1;while (start <= ps->size - 1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}
4.3 测试函数功能文件 test.c:
#include"Seqlist.h"void test1()
{SL s1;SLInit(&s1);SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);SLPushBack(&s1, 6);SLPopBack(&s1); SLPopBack(&s1);SLPrint(&s1);
}void test2()
{SL s2;SLInit(&s2);SLPushBack(&s2, 1);SLPushBack(&s2, 2);SLPushBack(&s2, 3);SLPushBack(&s2, 4);SLPushBack(&s2, 5);SLPushFront(&s2, 6);SLPrint(&s2);}void test3()
{SL s3;SLInit(&s3);SLPushBack(&s3, 1);SLPushBack(&s3, 2);SLPushBack(&s3, 3);SLPushBack(&s3, 4);SLPushBack(&s3, 5);SLPopFront(&s3);printf("头删:");SLPrint(&s3);
}void test4()
{SL s4;SLInit(&s4);SLPushBack(&s4, 1);SLPushBack(&s4, 2);SLPushBack(&s4, 3);SLPushBack(&s4, 4);SLPushBack(&s4, 5);SLInsert(&s4, 3, 6);SLPrint(&s4);}
void test5()
{SL s5;SLInit(&s5);SLPushBack(&s5, 1);SLPushBack(&s5, 2);SLPushBack(&s5, 3);SLPushBack(&s5, 4);SLPushBack(&s5, 5);SLErase(&s5, 3);SLPrint(&s5);}
int main()
{test1();test2();test3();test4();test5();return 0;
}
相关文章:

一起学数据结构(2)——线性表及线性表顺序实现
目录 1. 什么是数据结构: 1.1 数据结构的研究内容: 1.2 数据结构的基本概念: 1.2.1 逻辑结构: 1.2.2 存储结构: 2. 线性表: 2.1 线性表的基本定义: 2.2 线性表的运用: 3 .线性…...

mqtt协议流程图
转载于...

7、单元测试--测试RestFul 接口
单元测试–测试RestFul 接口 – 测试用例类使用SpringBootTest(webEnvironment WebEnvironment.RANDOM_PORT)修饰。 – 测试用例类会接收容器依赖注入TestRestTemplate这个实例变量。 – 测试方法可通过TestRestTemplate来调用RESTful接口的方法。 测试用例应该定义在和被测…...

国家留学基金委(CSC)|发布2024年创新型人才国际合作培养项目实施办法
2023年7月28日,国家留学基金委(CSC)发布了《2024年创新型人才国际合作培养项目实施办法》,在此知识人网小编做全文转载。详细信息请参见https://www.csc.edu.cn/chuguo/s/2648。 2024年创新型人才国际合作培养项目实施办法 第一章…...

找好听的配乐、BGM就上这6个网站,免费商用。
推荐几个音乐素材网站给你,各种类似、风格的都有,而且免费下载,还可以商用,建议收藏起来~ 菜鸟图库 https://www.sucai999.com/audio.html?vNTYxMjky 站内有上千首音效素材,网络流行的音效素材这里都能找到…...

【前端知识】React 基础巩固(三十五)——ReduxToolKit (RTK)
React 基础巩固(三十五)——ReduxToolKit (RTK) 一、RTK介绍 Redux Tool Kit (RTK)是官方推荐的编写Redux逻辑的方法,旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题。 RTK的核心API主要有如下几个: confi…...

android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案
android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案 1.查看当前的android studio 版本 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 2.打开 idea 官网下载页面 idea下载历史版本 找到对应的版本编号…...
前端框架学习-基础前后端分离
前端知识栈 前端三要素:HTML、CSS、JS HTML 是前端的一个结构层,HTML相当于一个房子的框架,可类比于毛坯房只有一个结构。CSS 是前端的一个样式层,有了CSS的装饰,相当于房子有了装修。JS 是前端的一个行为层ÿ…...

数据中心电子电气设备常见的五种地线种类和做法
数据中心机房计算机系统的集成化程度很高,其正常工作对环境的要求很严格。接地,是指电力系统和电气装置的中性点、电气设备的外露导电部分和装置外导电部分经由导体与大地相连。其作用主要是防止人身遭受电击、设备和线路遭受损坏、预防火灾和防止雷击、…...

重学C++系列之STL库
一、什么是STL库 STL是“Standard Template Library”的缩写,中文翻译为“标准模板库”。CSTL是一套功能强大的C模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如字符串操作、链表、队…...
JAVA SE -- 第十四天
(全部来自“韩顺平教育”) 泛型 一、泛型 1、基本介绍 ①泛型又称参数类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题 ②在类声明或实例化时只要指定好需要的具体的类型即可 ③Java泛型可以保证如果程序在编译时没有发…...

微信小程序监测版本更新
在index.js里面 不放到app.js里面是因为有登录页面,在登录页面显示更新不太友好 onShow() {const updateManager wx.getUpdateManager()// 请求完新版本信息的回调updateManager.onCheckForUpdate(res > {if (res.hasUpdate) {// 新版本下载成功updateManage…...

《Java面向对象程序设计》学习笔记——第 2 章 基本数据类型、数组和枚举类型
专栏:《Java面向对象程序设计》学习笔记...

TDesign中后台管理系统-访问后端服务
目录 1 修改后端服务地址2 解决跨域问题3 动态获取菜单4 测试后端接口5 前后端联调总结 目前我们已经搭建了TDesign的前端和express的后端,目前是两个独立的应用。通常我们需要把前后端集成在一起,TDesign已经配置了相关的信息,只需要修改后端…...

【机器学习】Gradient Descent for Logistic Regression
Gradient Descent for Logistic Regression 1. 数据集(多变量)2. 逻辑梯度下降3. 梯度下降的实现及代码描述3.1 计算梯度3.2 梯度下降 4. 数据集(单变量)附录 导入所需的库 import copy, math import numpy as np %matplotlib wi…...

ElasticSearch基础篇-Java API操作
ElasticSearch基础-Java API操作 演示代码 创建连接 POM依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sch…...
解决uniapp的tabBar使用iconfont图标显示方块
今天要写个uniapp的移动端项目,底部tabBar需要添加图标,以往都是以图片的形式引入,但是考虑到不同甲方的主题色也不会相同,使用图片的话,后期变换主题色并不友好,所以和UI商量之后,决定使用icon…...

UE4/5C++多线程插件制作(0.简介)
目录 插件介绍 插件效果 插件使用 English 插件介绍 该插件制作,将从零开始,由一个空白插件一点点的制作,从写一个效果到封装,层层封装插件,简单粗暴的对插件进行了制作: 插件效果 更多的是在cpp中去…...

ChatFile实现相关流程
文本上传构建向量库后台库的内容 调用上传文件接口先上传文件 存在疑问:暂时是把文件保存在tmp文件夹,定时清理,是否使用云存储 根据不同的文件类型选取不同的文件加载器加载文件内容 switch (file.mimetype) {case application/pdf:loader new PDFLoader(file.path)breakc…...

15 文本编辑器vim
15.1 建立文件命令 如果file.txt就是修改这个文件,如果不存在就是新建一个文件。 vim file.txt 使用vim建完文件后,会自动进入文件中。 15.2 切换模式 底部要是显示插入,是编辑模式; 按esc,底部要是空白的࿰…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...