【数据结构初阶】二、 线性表里的顺序表

=========================================================================

相关代码gitee自取

C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期

【数据结构初阶】一. 复杂度讲解_高高的胖子的博客-CSDN博客

 =========================================================================

                     

1 . 线性表

               

线性表linear list)是n个具有相同特性的数据元素的有限序列

线性表是一种在实际中广泛使用的数据结构

常见线性表顺序表链表队列字符串...

顺序表示例:

              

              

线性表逻辑上线性结构,也就说是连续的一条直线

但是在物理结构上并不一定是连续的

线性表物理上存储时,通常以数组链式结构形式存储

链表示例:

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

2 . 顺序表

顺序表概念及结构:

               

顺序表一段物理地址连续的存储单元依次存储数据元素线性结构

一般情况下采用数组存储

数组上完成数据的增删查改

顺序表一般可以分为 静态顺序表动态顺序表

               

               

静态顺序表:使用定长数组存储元素

                

因为静态顺序表使用定长数组存储元素

对空间的运用不够灵活,可能造成空间浪费或不够的问题
所以在实际情况下静态顺序表并不常用不够实用

示例:

                    

                    

动态顺序表:使用动态开辟的数组存储元素

             

静态顺序表适用于确定知道需要存多少数据的场景

静态顺序表定长数组导致N定大了空间开多了浪费开少了不够用

所以现实中基本都是使用动态顺序表根据需要动态地分配空间大小

示例:

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

3 .接口实现(实现动态顺序表):

(详细解释在注释,代码分文件放最后)

                

数据结构可以管理数据

通过 增删改查 等操作就可以实现管理数据

              

现在有了动态顺序表后

就可以对其进行增删改查等操作实现动态顺序表

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLInit函数 -- 顺序表初始化

                      

                      

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLDestroy函数 -- 顺序表销毁

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPrint函数 -- 测试函数

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPushBack函数 -- 将值插入顺序表尾部(尾插)

尾插函数SLPushBack测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

上面尾插需要考虑空间不够进行扩容

后面的头插同样也需要考虑

所以可以在顺序表实现文件设置一个内部函数SLCheckCapacity,

在需要的时候直接调用该函数进行扩容操作

↓↓↓↓↓

                 

SLCheckCapacity内部函数 -- 进行扩容操作

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPopBack函数 -- 将值从顺序表尾部删除(尾删)

尾删函数SLPopBack测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPushFront函数 -- 将值插入顺序表头部(头插)

头插函数SLPushFront测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPopFront函数 -- 将值从顺序表头部删除(头删)

头删函数SLPopFront测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLInsert函数 -- 在指定位置(pos)插入想要的值(x)

指定添加函数SLInsert测试:

             

这里写了指定位置插入SLInsert函数

可以想到其实 头插 尾插 也是可以用 SLInsert函数 实现的

所以可以在头插和尾插函数中复用 SLInsert函数减少代码量

↓↓↓↓↓

                  

复用SLInsert函数 -- 改写头插函数SLPushFront

                     

复用SLInsert函数 -- 改写尾插函数SLPushBack

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

上面SLInsert函数涉及了插入位置pos下标

有时在增删改查操作时,需要知道有效元素中某个元素的下标再进行操作,

所以我们可以定义一个函数SLFind查找该元素的下标

↓↓↓↓↓

                 

SLFind函数 -- 查找x这个值在顺序表中的下标是多少

查找函数SLFind测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLErase函数 -- 删除指定位置(pos)的值

删除指定位置函数SLErase测试:

                   

完成指定删除SLErase函数

头删 尾删 函数中也可以进行复用 SLErase函数 减少代码量

↓↓↓↓↓

                  

用SLErase函数 -- 改写头删函数SLPopFront

                     

用SLErase函数 -- 改写尾删函数SLPopBack

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLModify函数 -- 把某个位置(pos)的值修改为某值(x)

修改函数SLModify测试:

          

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

4 . 对应代码

SeqList.h -- 顺序表头文件

#pragma once定义一个静态顺序表:使用定长数组存储元素
因为静态顺序表使用定长数组存储元素,对空间的运用不够灵活
所以在实际情况下,静态顺序表并不常用(不够实用)
//
//#define N 1000  //“表”的大小的值
//typedef int SLDataType;  //定义顺序表中存储的类型,这里是int类型
//
//struct SeqList
//{
//	SLDataType a[N]; //定义表的大小
//	int size; //记录表中存储了多少个有效数据
//};//将需要的头文件都包含在 SeqList.h 头文件中
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>//定义一个动态顺序表:使用动态开辟的数组存储元素
typedef int SLDataType;  //定义顺序表中存储的类型,这里是int类型typedef struct SeqList
{//定义一个顺序表类型的指针,指向动态开辟的数组SLDataType* a; int size; //记录表中存储了多少个有效数据int capactity; //容量空间的大小
}SL;//数据结构 --> 管理数据 --> 增删查改//顺序表初始化  --  头文件中声明
void SLInit(SL* ps); //顺序表销毁 --  头文件中声明
//内存是动态开辟地,不销毁的话可能会导致内存泄漏)
void SLDestroy(SL* ps);//写一个测试函数(声明),方便检查各步骤有没有问题:
void SLPrint(SL* ps);//尾插(声明) -- 将值插入顺序表尾部:
void SLPushBack(SL* ps, SLDataType x);//尾删(声明) -- 将值从顺序表尾部删除:
void SLPopBack(SL* ps);//头插(声明) -- 将值插入顺序表头部:
void SLPushFront(SL* ps, SLDataType x);//头删(声明) -- 将值从顺序表头部删除:
void SLPopFront(SL* ps);//在指定位置(pos)插入想要的值(x)
void SLInsert(SL* ps, int pos, SLDataType x);//查找x这个值在顺序表中的下标是多少:
int SLFind(SL* ps, SLDataType x); //返回找到的下标//删除指定位置(pos)的值:
void SLErase(SL* ps, int pos);//把某个位置(pos)的值修改为某值(x)
void SLModify(SL* ps, int pos, SLDataType x);

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SeqList.c -- 顺序表实现文件

#define _CRT_SECURE_NO_WARNINGS 1//包含我们写的 SeqList.h 头文件
#include "SeqList.h"//顺序表初始化 -- 实现
void SLInit(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//初始化顺序表类型指针//初始化时要先开辟一些动态空间://开辟的空间为顺序表类型,大小为4个顺序表类型的大小ps->a = (SLDataType*)malloc(sizeof(SLDataType)*4); //顺序表作为一个独立的程序,之后可能会应用于其他程序,//所以要对开辟的动态空间进行检查:if (ps->a == NULL){//可能开辟的空间过大 或 前面开辟太多空间不够再开辟perror("malloc failed");  //打印错误//让程序以异常的形式结束程序//和 return 不同,return后主函数还会继续进行exit(-1);}//将顺序表中的有效数据初始化为0:ps->size = 0;//将已动态开辟的容量空间初始化为4:ps->capactity = 4;
}//顺序表销毁 -- 实现
//内存是动态开辟地,不销毁的话可能会导致内存泄漏)
void SLDestroy(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//释放前面开辟的动态空间:free(ps->a);//将释放的指针置为空指针:ps->a = NULL;//将已开辟的动态空间置为0,顺序表有效数据也置为0ps->capactity = ps->size = 0;
}//写一个测试函数(实现),方便检查各步骤有没有问题:
void SLPrint(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//打印动态顺序表现有的有效数据:for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}//打印完当前动态顺序表有效数据后进行换行:printf("\n");
}//在顺序表实现文件中设置一个内部函数SLCheckCapacity,
//在需要的时候直接调用该函数进行扩容操作
void SLCheckCapacity(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//判断开辟的空间是否已满,满了再开辟:if (ps->size == ps->capactity)//顺序表有效个数 等于 已开辟容量空间{//使用 realloc函数 进行扩容,每次扩容2倍:SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capactity * 2 * (sizeof(SLDataType)));// realloc 是把空间扩容到第二个参数的大小,而不是直接把空间扩容第二个参数的大小//同样进行检验:if (tmp == NULL){//打印错误:perror("realloc failed");//出现错误直接终止程序:exit(-1);}//realloc函数,有两种扩容情况:一种是原地扩容,另一种是异地扩容//原地扩容:扩容时看原空间后的内容有没有分配给别人,如果没有则把原空间后面的空间标记出来进行扩容,返回原空间的地址//异地扩容:如果扩容时原空间后面的内容已被分配,则另找一个足够原空间扩容后的空间进行存放,//		   原本的数据都搬到这个空间来,原空间会被释放,返回这个新空间的地址。//所以使用 realloc函数 扩容后,不要对原空间指针进行释放,//如果realloc执行后是原地扩容返回原空间指针,扩容后后对原空间指针释放就会出问题//把扩容返回的指针赋给原指针:ps->a = tmp;//将已动态开辟的容量空间置为原来的2倍:ps->capactity *= 2;}
}//尾插(实现) -- 将值插入顺序表尾部:
void SLPushBack(SL* ps, SLDataType x)
{//assert断言,防止接收空指针:assert(ps);调用内部函数进行扩容操作://SLCheckCapacity(ps);空间容量足够后将要插入尾部的值插入://ps->a[ps->size] = x; 因为下标从0开始,所以size的值会等于现有元素下一位的下标//ps->size++; //尾部插入元素后,更新顺序表中有效数据个数//复用SLInsert函数 -- 改写尾插函数SLPushBackSLInsert(ps, ps->size, x); //在size位置插入就相当于尾插
}//尾删(实现) -- 将值从顺序表尾部删除:
void SLPopBack(SL* ps)
{//assert断言,防止接收空指针:assert(ps);检查一下:如果有效数据size等于0,则不能继续删除了防止越界,可能一直删除到空间外了导致越界//检查方法一:太“温柔”,返回后不知道自己错了if (ps->size == 0){return; //直接返回 即可}//检查方法二:使用断言,错误了会直接报错并给出错误信息//assert(ps->size > 0); //顺序表中有效数据大于0才进行下面的操作直接有效数据size--即可尾插是也是用size插入的,所以下次添加时直接就覆盖了原来值//ps->size--;不能局部释放,不能说不要末尾的值就把末尾的这个空间直接释放掉C++有个规定,malloc一次就要free一次,要free释放的话只能整体释放顺序表的物理内存是连续的,释放空间是不能“分期”的//复用SLErase函数 -- 改写尾删函数SLPopBackSLErase(ps, ps->size-1); //size-1 就是最末元素下标
}//头插(实现) -- 将值插入顺序表头部:
void SLPushFront(SL* ps, SLDataType x)
{//assert断言,防止接收空指针:assert(ps);调用内部函数进行扩容操作://SLCheckCapacity(ps);将现有有效数据往后移一位,让出头位置://int end = ps->size - 1; size-1 有效个数-1,就相当于当前最后一个元素的下标//while (end >= 0)//	//使用while循环循环移动各个有效元素,一直移到下标为0的元素//{//	ps->a[end + 1] = ps->a[end]; //end下标元素 移到 下一位上//	--end; //改变下标//}将要插入头部的元素x插入头部://ps->a[0] = x;有效个数加一://ps->size++;Capacity在扩容函数SLCheckCapacity中就修改好了//复用SLInsert函数 -- 改写头插函数SLPushFrontSLInsert(ps, 0, x); //在0位置插入就相当于头插
}//头删(实现) -- 将值从顺序表头部删除:
void SLPopFront(SL* ps)
{//assert断言,防止接收空指针:assert(ps);因为要将头部的有效元素删除,所以直接把第一个有效元素后面的其他元素往前移一位就行了,覆盖掉第一个元素先进行断言检查,防止没有元素还进行删除://assert(ps->size > 0);//int begin = 1; //从下标为1的元素开始往前移,把下标为0的元素覆盖//while (begin < ps->size)//	//只要begin还小于有效元素个数就继续往前移//	//因为是从下标为1的元素开始移动,//	//所以最后就只有下标为0的元素没动//{//	//把当前begin下标的元素往前挪一位://	ps->a[begin - 1] = ps->a[begin]; //	//当前begin下标元素移动后,begin++继续移动下一位://	++begin;//}//因为第一个元素被覆盖,所以有效元素size--//ps->size--;//复用SLErase函数 -- 改写头删函数SLPopFrontSLErase(ps, 0); //头元素下标是0
}//在指定位置(pos)插入想要的值(x)
void SLInsert(SL* ps, int pos, SLDataType x)
{//先使用assert检查pos是否合法://在pos位置插入一个值后,顺序表还得是连续的assert(pos >= 0 && pos <= ps->size);//pos等于0 -- 相等于头插//pos等于size -- 相等于尾插//使用SLCheckCapacity进行扩容操作:SLCheckCapacity(ps);//定义一个变量end,对应要移动元素的下标int end = ps->size - 1; //一开始对应最后一个元素的下标while (end >= pos)//只要end下标对应的元素还在pos下标元素的右边//就把“end元素”向右移,移到pos下标无元素{//把“end元素”向右移ps->a[end + 1] = ps->a[end];//移动下标进行写一个元素的移动--end;}//让出位置后,将接收的x插入pos位置:ps->a[pos] = x;//有效元素+1:ps->size++;
}//查找x这个值在顺序表中的下标是多少:
int SLFind(SL* ps, SLDataType x) //返回找到的下标
{//assert断言,防止接收空指针:assert(ps);//数据量不大的话直接暴力查找吧:for (int i = 0; i < ps->size; i++)//有几个有效元素就循环几次:{if (ps->a[i] == x)//该下标元素等于要找的值x则返回当前下标:{return i;}}return -1; //表未找到该元素下标
}//删除指定位置(pos)的值:
void SLErase(SL* ps, int pos)
{//同样先使用assert检查pos是否合法://这里检查条件pos不能像SLInsert一样等于size//因为size空了能插入(尾插),但不能删除assert(pos >= 0 && pos < ps->size);//指定删除和头删的思路类似,//只要把pos后面的值往前覆盖,覆盖掉pos的值就好了:int begin = pos + 1; //从pos+1的位置往前挪while (begin < ps->size)//一直移到size为止(不包括size位置){ps->a[begin - 1] = ps->a[begin]; //往前挪++begin; //挪完继续挪下一个 }ps->size--; //覆盖掉pos位置的值后,有效数字减一
}//把pos位置的值修改为x
void SLModify(SL* ps, int pos, SLDataType x)
{//同样先使用assert断言检查pos是否合法:assert(pos >= 0 && pos < ps->size);//进行修改:ps->a[pos] = x;
}

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

test.c -- 测试函数

#define _CRT_SECURE_NO_WARNINGS 1//包含我们写的 SeqList.h 头文件
#include "SeqList.h"//分组测试,测试不同的函数--SLPushBack 和 SLPopBack 函数
void TestSeqList1()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试尾删函数SLPopBack:SLPopBack(&sl);SLPopBack(&sl);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLPushFront函数
void TestSeqList2()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试头插函数SLPushFront:SLPushFront(&sl, 10);SLPushFront(&sl, 20);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLPopFront函数
void TestSeqList3()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试头删函数SLPopFront:SLPopFront(&sl);SLPopFront(&sl);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLInsert函数
void TestSeqList4()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试指定增加函数SLInsert:SLInsert(&sl, 2, 100);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//int x;//scanf("%d", &x);//int pos = SLFind(&sl, x);//if (pos != -1)//{//	SLInsert(&sl, pos, x * 10);//}//SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLFind函数
void TestSeqList5()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试指定增加函数SLFind:int pos = SLFind(&sl, 2);printf("2在元素中是第%d个元素", pos+1);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLErase函数
void TestSeqList6()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);int x;scanf("%d", &x);//配合SLFind函数,找到顺序表中某个值的下标int pos = SLFind(&sl, x);//再使用SLErase函数通过下标删除该值if (pos != -1){SLErase(&sl, pos);}SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLModify函数
void TestSeqList7()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试指定增加函数SLInsert:SLModify(&sl, 2, 100);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//菜单:
void menu()
{printf("********************************\n");printf("1、尾插			2、头插\n");printf("3、头删			4、尾删\n");printf("7、打印			-1、退出\n");printf("********************************\n");
}int main()
{//先创建一个顺序表:SL sl;//再对其进行初始化:SLInit(&sl);//创建一个变量接收菜单选项:int option = 0;do{//使用菜单:menu();//打印提示信息:printf("请选择想要进行的操作的序号:>");//接收序号:scanf("%d", &option);printf("\n");if (option == 1){printf("请依次输入你要插入的数据个数:>");int n = 0; //接收数据个数scanf("%d", &n); //接收数据个数printf("\n");printf("请依次输入你要插入的数据\n");//知道数据个数后,直接使用for循环循环接收数据int x = 0;for (int i = 0; i < n; i++){scanf("%d", &x);SLPushBack(&sl, x);}}else if (option == 7){SLPrint(&sl);}} while (option != -1);//最后销毁顺序表:SLDestroy(&sl);//TestSeqList1();//TestSeqList2();//TestSeqList3();//TestSeqList4();//TestSeqList5();//TestSeqList6();//TestSeqList7();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/103278.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Linux]动静态库

[Linux]动静态库 文章目录 [Linux]动静态库见一见库存在库的原因编写库模拟编写静态库模拟使用静态库模拟编写动态库模拟使用静态库 库的加载原理静态库的加载原理动态库的加载原理 库在可执行程序中的编址策略静态库在可执行程序中的编址策略动态库在可执行程序中的编址策略 见…

TinTin Web3 动态精选:以太坊基金会推出 EELS、Arbitrum Stylus 上线

TinTin 快讯由 TinTinLand 开发者技术社区打造&#xff0c;旨在为开发者提供最新的 Web3 新闻、市场时讯和技术更新。TinTin 快讯将以周为单位&#xff0c; 汇集当周内的行业热点并以快讯的形式排列成文。掌握一手的技术资讯和市场动态&#xff0c;将有助于 TinTinLand 社区的开…

YOLO目标检测——红火蚂蚁识别数据集+已标注yolo格式标签下载分享

实际项目应用&#xff1a;目标检测红火蚂蚁识别数据集在农业、生态学、环境保护、城市管理和学术研究等领域都有着广泛的应用。通过准确识别和定位红火蚂蚁&#xff0c;可以帮助我们更好地了解和管理这一入侵物种&#xff0c;从而减少其对环境和经济的负面影响。数据集说明&…

基于Docker从零到一实操MySql的主从复制

文章目录 一、在Docker上安装&#xff0c;启动MySQL查看docker是否安装成功安装mysql查看mysql镜像进入mysql后台操作docker Volume&#xff08;卷&#xff09;入门 MySql的主从复制1. 创建MySQL主从复制的网络2. 创建MySQL主服务器3. 创建MySQL从服务器4. 配置主从同步5.测试主…

Activiti7工作流引擎:在线流程编辑器Activiti Modoler5.x

一&#xff1a;简介 有的时候我们的流程图需要业务人员自己绘制&#xff0c;然后使用自己绘制的流程图&#xff0c;此时就需要一个在线流程图编辑器需要集成到我们的web系统中。Activiti Modoler是Activiti官方推出的在线流程编辑器。 二&#xff1a;pom.xml <dependency…

Python - 队列【queue】task_done()和join()基本使用

一. 前言 task_done()是Python中queue模块提供的方法&#xff0c;用于通知队列管理器&#xff0c;已经处理完了队列中的一个项目。 queue.task_done()是Queue对象的一个方法&#xff0c;它用于通知Queue对象&#xff0c;队列中的某一项已经被处理完毕。通常在使用Queue对象时…

电脑磁盘分区形式是什么?如何更改?

磁盘分区形式介绍 在了解为什么以及如何更改分区形式之前&#xff0c;让我们对磁盘分区形式有一个基本的了解。一般来说&#xff0c;分区形式是指主引导记录&#xff08;MBR&#xff09;和 GUID 分区表&#xff08;GPT&#xff09;。 MBR和GPT是Windows系统中常用…

洛谷 LGR SCP-J 2023 c++语言模拟试题 10. 以下程序片段的时间复杂度为( )

之前在牛客的一个群中看到有位哥们发的题 好像是洛谷哪次的模拟题&#xff0c;还写着什么 LGR SCP-J 2023 c语言模拟试题 题目 就是给段代码询问时间复杂度 for (int i1; i<n; i){for (int j1; j<n; ji){for (int k1; k<n; k j){}} } 跑代码 一开始想不出怎么解就…

【CMake工具】工具CMake编译轻度使用(C/C++)

目录 CMake编译工具 一、CMake概述 二、CMake的使用 2.1 注释 2.1.1 注释行 2.1.2 注释块 2.2 源文件 2.1.1 共处一室 2.1.2 VIP包房 2.3 私人定制 2.2.1 定义变量 2.2.2 指定使用的C标准 2.2.3 指定输出的路径 2.4 搜索文件 2.3.1 方式1 2.3.2 方式2 2.5 包含…

岩土工程安全监测利器:振弦采集仪的发展

岩土工程安全监测利器&#xff1a;振弦采集仪的发展 岩土工程安全监测是保障建筑物、地下工程和地质环境安全稳定运行的重要手段。传统上&#xff0c;监测手段主要依靠人工巡视以及基础设施安装的传感器&#xff0c;但是这些方法都存在着缺陷。人工巡视存在的问题是数据采集精…

云原生Kubernetes:pod基础

目录 一、理论 1.pod 2.pod容器分类 3.镜像拉取策略&#xff08;image PullPolicy&#xff09; 二、实验 1.Pod容器的分类 2.镜像拉取策略 三、问题 1.apiVersion 报错 2.pod v1版本资源未注册 3.取行显示指定pod信息 四、总结 一、理论 1.pod (1) 概念 Pod是ku…

CASAIM与南京航空航天大学在自动化叶片曲面分析系统开展合作,推动航空航天发动机零部件自动化3D检测进程

近期&#xff0c;CASAIM与南京航空航天大学在自动化叶片曲面分析系统展开深入合作&#xff0c;充分发挥双方在航空航天和智能检测领域优势&#xff0c;共同推动航空航天发动机零部件自动化3D检测进程。 南京航空航天大学创建于1952年10月&#xff0c;是新中国自己创办的第一批…