当前位置: 首页 > news >正文

【数据结构】万字超详解顺序表(比细狗还细)

我这个人走得很慢,但是我从不后退。                                ——亚伯拉罕·林肯

 

目录

一.什么是线性表?

二.什么是顺序表?

三.接口函数的实现

1.创建工程

2.构造顺序表

3.初始化顺序表

3.初始化顺序表

4.顺序表的尾插

5.顺序表的头插 

6.顺序表的尾删 

7.顺序表的头删 

8.在顺序表中查找一个数 

9.在顺序表中指定位置插入

10.在顺序表中指定位置删除 

11.在头插和尾插的功能实现可以使用指定位置插入的函数进行复用

四.很被动的实现顺序表

1.SeqList.h:

2.SeqList.c:

3.test.c:

五.以菜单的形式玩转顺序表 

1.以菜单的形式写顺序表

六.主动的输入实现顺序表全部功能的代码

1.SeqList.h:

2.SeqList.c:

3.test.c:


一.什么是线性表?

线性表是最基本、最简单、也是最常用的一种数据结构。线性表是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储,但是把最后一个数据元素的尾指针指向了首位结点)。

常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

二.什么是顺序表?

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改

顺序表其实就是数组,但是在数组的基础上,它还要求数据是从头开始的,并且是连续储存的不能跳跃间隔

这句话什么意思呢?我们举个例子来看:

#include<stdio.h>
int main()
{int arr[5] = { 0 };arr[4] = 5;arr[1] = 6;for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}
}

可以看出:数组可以跳着存入数据,不一定要连续。

总结:数组内存是连续的,但是储存数据可以不连续。 所以顺序表在数组的基础上还有一定的要求。

三.接口函数的实现

1.创建工程

创建工程我们也是像三子棋那样创建三个文件。SeqList.c,SeqList.h和test.c。

SeqList.h:函数的声明以及各种头文件。

SeqList.c:函数的实现,定义。

test.c:书写程序整体执行逻辑。

2.构造顺序表

构造顺序表一般有两种。

第一种:静态顺序表,使用定长数组来实现顺序表。



静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开秒了不够用。

所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

第二种:动态顺序表,使用动态开辟的数组。
 

动态顺序表相对于静态顺序表来说,优点就是空间不够可以增容。

3.初始化顺序表

typedef int SLDateType;
typedef struct SeqList
{SLDateType* a; //动态数组size_t size; //有效的数据个数size_t Capacity; //数组的容量大小
}SL;

这里我们使用了两个typedef(类型重定义)。

第一个typedef将int定义为SLDateType,如果要定义其他的数据类型,如double,short,char等等只需要改变类型重定义这里,后面的也会跟着改变。

第二个typedef将结构体重新命名为SL。为了后面写结构体名称时,不那么麻烦,更方便简洁。

3.初始化顺序表

void SeqListInit(SL ps)//ps是形参
{ps.a = 0;ps.size = ps.Capacity = 0;
}

 所以我们应当写成指针的形式,使用传址调用,这样改变形参也就会改变实参了。

正确的写法:

  //初始化顺序表
void SeqListInit(SL*ps)
{ps->a = NULL;//先将动态数组置为空指针ps->size = ps->Capacity = 0;//有效个数和容量大小都设为0
}

4.顺序表的尾插

尾插目的就是在动态数组的结尾开始放入数据,逐渐填充数组。

思路:

1.刚开始size和Capacity都初始化为的0,两个大小相等,肯定没法存放数据。然后我们开始扩容,把Capacity的值扩大为两倍,但是第一次Capacity的值为0,扩大两倍还是0。所以第一次我们把Capacity的值扩大为4下一次就依次扩大为两倍。

2.然后把扩容的大小赋给动态数组的大小。

3.对动态数组进行尾插进数据,每插一个数据进去,a就加一次,直到a和Capacity的值大小一致,又重复1步骤,继续扩容。

//尾插
void SeqListPushBack(SL*ps, SLDateType x)
{if (ps->size == ps->Capacity)//初始化都为0,肯定if成立进入语句{                              //这里一定要写成==,因为这里判断语句int NewCapacity = ps->Capacity == 0 ? 4 : ps->Capacity * 2;//这里使用一个三目操作符SLDateType* temp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * NewCapacity);if (temp == NULL)//如果开辟空间错误{printf("realloc is error\n");exit(-1);//退出程序}ps->a = temp;ps->Capacity = NewCapacity;}ps->a[ps->size] = x;ps->size++;
}

在test.c中的文件中,下面是我们要插入的5个数字。 

void SeqListtest1()
{SL s1;SeqListInit(&s1);SeqListPushBack(&s1, 1);SeqListPushBack(&s1, 2);SeqListPushBack(&s1, 3);SeqListPushBack(&s1, 4);SeqListPushBack(&s1, 5);
}

我们再写一个打印函数,打印一下我们尾插的数据。 

//打印函数
void SeqListprint(SL* ps) 
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}

这里说明我们尾插成功了,还是非常喜悦的。然后我们开始头插。

5.顺序表的头插 

头插的方法:

注意事项:在头插的时候我们也要考虑容量的大小和数据个数的大小的关系,不够了,就要扩容。 尾插的时候也要考虑这种情况。我们不妨把扩容写成一个函数。每次有地方要扩容时,就调用一次,这样就很方便。

检查容量的函数:

//检查容量
void SeqListCheckCapacity(SL* ps)
{if (ps->size == ps->Capacity)//初始化都为0,肯定if成立进入语句{                              //这里一定要写成==,因为这里判断语句int NewCapacity = ps->Capacity == 0 ? 4 : ps->Capacity * 2;//这里使用一个三目操作符SLDateType* temp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * NewCapacity);if (temp == NULL)//如果开辟空间错误{printf("realloc is error\n");exit(-1);//退出程序}ps->a = temp;ps->Capacity = NewCapacity;}
}

开始头插:

//头插
void SeqListPushFront(SL* ps, SLDateType x)
{SeqListCheckCapacity(ps);//检查容量int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}

 我们头插6,7两个数之后,打印出来看一下。

    SeqListPushFront(&sl, 6);SeqListPushFront(&sl, 7);SeqListprint(&sl);

6.顺序表的尾删 

尾删的方法非常简单,我们只需要把ps->size的值--即可,这样最后的数据自然会被删除。

//尾删
void SeqListPopBack(SL* ps)
{assert(ps->size > 0);//这里断言一下,如果ps->size小于0之后,直接报错ps->size--;
}

 这里调用三次尾删函数,所以就会依次删除三个后面的数字。

//尾删printf("尾删之后为 ");SeqListPopBack(&sl);SeqListPopBack(&sl);SeqListPopBack(&sl);SeqListprint(&sl);

7.顺序表的头删 

头删和头插的方法其实很相似,头插是往后面移动数据,而头删就是相反的,往前面移动数据。

后一个数字把前一个数字给覆盖掉,也就是头删了。

开始头删: 

//头删
void SeqListPopFront(SL* ps)
{int start = 0;while (start < ps->size){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}

8.在顺序表中查找一个数 

//在数组里面找一个数字,找到就返回下标,否则就是返回-1
int SeqListfind(SL* ps, SLDateType x)
{int i = 0;while (i < ps->size){if (ps->a[i] == x){return i;}i++;}return -1;
}
//在数组里面找一个数字,找到就返回下标,否则就是返回-1int ret=SeqListfind(&sl, 1);if (ret != -1){printf("找到数字1的下标为%d\n", ret);}elseprintf("没找到\n");

9.在顺序表中指定位置插入

这个和头插是很相似的,只需要把你要指定的位置给往后面移动一位,然后你再把要插入的数字给填到空缺的位置即可。

注意事项:在插入数据的时候,我们必须要判断ps->size和ps->Capacity容量的大小。

即:判断容量的大小,所以我们在插入数据之前,需要调用检查容量的函数。

//在指定的位置插入一个数字
void  SeqListInsert(SL* ps, int pos, SLDateType x)//pos是指定的下标位置
{SeqListCheckCapacity(ps);//检查容量int end = ps->size-1;while (end>=pos){ps->a[end+1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}

10.在顺序表中指定位置删除 

这和头删是很相似的,只需要把指定的位置的后面的位置依次往前一位,把指定位置的地方给覆盖掉。

//在指定位置删除一个数字
void SeqListErase(SL* ps, int pos)
{int end = pos;while (end < ps->size){ps->a[end] = ps->a[end + 1];end++;}ps->size--;
}

11.在头插和尾插的功能实现可以使用指定位置插入的函数进行复用

之前说了在指定位置插入函数的功能实现是和头插和尾插函数是很相似的,这里我们就可以复用这个函数,来简化代码。

  //头插
void SeqListPushFront(SL* ps, SLDateType x)
{SeqListCheckCapacity(ps);//检查容量SeqListInsert(ps, 0, x);//调用插入函数来复用头插,头插就是在0的位置进行插入
}
  //头插
void SeqListPushFront(SL* ps, SLDateType x)
{SeqListCheckCapacity(ps);//检查容量SeqListInsert(ps, 0, x);//调用插入函数来复用头插,头插就是在0的位置进行插入
}

四.很被动的实现顺序表

1.SeqList.h:

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLDateType;
typedef struct SeqList
{SLDateType* a; //动态数组size_t size; //有效的数据个数size_t Capacity; //数组的容量大小
}SL;
//初始化顺序表
void SeqListInit(SL*ps);//尾插
void SeqListPushBack(SL*ps, SLDateType x);//打印数据
void SeqListprint(SL* ps);//头插
void SeqListPushFront(SL* ps, SLDateType x);//尾删
void SeqListPopBack(SL* ps);//头删
void SeqListPopFront(SL* ps);//在数组里面找一个数字,找到就返回下标,否则就是返回-1
int SeqListfind(SL* ps, SLDateType x);//在指定的位置插入一个数字
void SeqListInsert(SL* ps, int pos, SLDateType x);//pos是指定的下标位置//在指定位置删除一个数字
void SeqListErase(SL* ps, int pos);

2.SeqList.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//检查容量
void SeqListCheckCapacity(SL* ps)
{if (ps->size == ps->Capacity)//初始化都为0,肯定if成立进入语句{                              //这里一定要写成==,因为这里判断语句int NewCapacity = ps->Capacity == 0 ? 4 : ps->Capacity * 2;//这里使用一个三目操作符SLDateType* temp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * NewCapacity);if (temp == NULL)//如果开辟空间错误{printf("realloc is error\n");exit(-1);//退出程序}ps->a = temp;ps->Capacity = NewCapacity;}
}//初始化顺序表
void SeqListInit(SL*ps)
{ps->a = NULL;//先将动态数组置为空指针ps->size = ps->Capacity = 0;//有效个数和容量大小都设为0
}//尾插
void SeqListPushFront(SL* ps, SLDateType x)
{SeqListCheckCapacity(ps);//检查容量SeqListInsert(ps, ps->size, x);//调用插入函数来复用尾插,尾插就是在ps->size的位置进行插入
}//打印函数
void SeqListprint(SL* ps) 
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//头插
void SeqListPushFront(SL* ps, SLDateType x)
{SeqListCheckCapacity(ps);//检查容量SeqListInsert(ps, 0, x);//调用插入函数来复用头插,头插就是在0的位置进行插入
}
//尾删
void SeqListPopBack(SL* ps)
{assert(ps->size > 0);//这里断言一下,如果ps->size小于0之后,直接报错ps->size--;
}
//头删
void SeqListPopFront(SL* ps)
{int start = 0;while (start < ps->size){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}
//在数组里面找一个数字,找到就返回下标,否则就是返回-1
int SeqListfind(SL* ps, SLDateType x)
{int i = 0;while (i < ps->size){if (ps->a[i] == x){return i;}i++;}return -1;
}
//在指定的位置插入一个数字
void  SeqListInsert(SL* ps, int pos, SLDateType x)//pos是指定的下标位置
{SeqListCheckCapacity(ps);//检查容量int end = ps->size-1;while (end>=pos){ps->a[end+1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
//在指定位置删除一个数字
void SeqListErase(SL* ps, int pos)
{int end = pos;while (end < ps->size){ps->a[end] = ps->a[end + 1];end++;}ps->size--;
}

3.test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"SL sl;
void SeqListtest1()
{SeqListInit(&sl);//初始化顺序表//尾插printf("尾插的数据为 ");SeqListPushBack(&sl, 1);SeqListPushBack(&sl, 2);SeqListPushBack(&sl, 3);SeqListPushBack(&sl, 4);SeqListPushBack(&sl, 5);SeqListprint(&sl);//打印函数printf("\n");//头插printf("头插之后为 ");SeqListPushFront(&sl, 6);SeqListPushFront(&sl, 7);SeqListprint(&sl);printf("\n");
}
void SeqListtest2()
{//尾删printf("尾删之后为 ");SeqListPopBack(&sl);SeqListPopBack(&sl);SeqListPopBack(&sl);SeqListprint(&sl);printf("\n");//头删printf("头删之后 ");SeqListPopFront(&sl);SeqListprint(&sl);printf("\n");
}
void SeqListtest3()
{//在数组里面找一个数字,找到就返回下标,否则就是返回-1int ret=SeqListfind(&sl, 1);if (ret != -1){printf("找到数字1的下标为%d\n", ret);}elseprintf("没找到\n");//在指定的位置插入一个数字printf("在下标为1的位置插入数字后为 ");SeqListInsert(&sl, 1, 8);SeqListprint(&sl);//在指定位置删数字printf("在下标为2的删除数字后为 ");SeqListErase(&sl,2);SeqListprint(&sl);
}int main()
{SeqListtest1();SeqListtest2();SeqListtest3();return 0;
}

五.以菜单的形式玩转顺序表 

1.以菜单的形式写顺序表

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"SL sl;SL* ps;void test()
{printf("\n*********************************\n");printf("1.尾插  2.头插\n");printf("3.尾删  4.头删\n");printf("5.指定删 6.指定插\n");printf("7.找一个数  -1.退出\n");printf("**********************************\n");printf("请选择你要进行的操作:>\n");
}
void Menutest()
{SL sl;SeqListInit(&sl);int x = 0;int y = 0;int input = 0;while (input != -1){test();//每一次输入结束了,都会再次打印菜单scanf("%d", &input);switch (input){case 1:{printf("请你输入要尾插的数字,以-1结束:");scanf("%d", &x);while (x != -1)//还是有缺陷,不能插入-1{SeqListPushBack(&sl, x);scanf("%d", &x);}printf("尾插之后为:");SeqListprint(&sl);break;}case 2:{printf("请你输入要头插的数字,以-1结束:");scanf("%d", &x);while (x != -1){SeqListPushFront(&sl, x);scanf("%d", &x);}printf("尾插之后为:");SeqListprint(&sl);break;}case 3:{SeqListPopBack(&sl);printf("尾删之后为:");SeqListprint(&sl);break;}case 4:{SeqListPopFront(&sl);printf("头删之后为:");SeqListprint(&sl);break;}case 5:{printf("请你输入要删数字的下标:");scanf("%d", &x);SeqListErase(&sl, x);printf("删除数字后:");SeqListprint(&sl);break;}case 6:{printf("请你输入要插数字的下标和数字:");scanf("%d %d", &x, &y);SeqListInsert(&sl, x, y);printf("插入数字后:");SeqListprint(&sl);break;}case 7:{printf("请你输入你要找的数字:");scanf("%d", &x);int ret = SeqListfind(&sl, x);if (ret != -1){printf("查找的坐标为:");printf("%d", ret);}break;}default:printf("选择错误,请重新输入");break;}}
}
int main()
{Menutest();SeqlistDestory(&sl);return 0;
}

六.主动的输入实现顺序表全部功能的代码

1.SeqList.h:

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLDateType;
typedef struct SeqList
{SLDateType* a; //动态数组size_t size; //有效的数据个数size_t Capacity; //数组的容量大小
}SL;
//初始化顺序表
void SeqListInit(SL*ps);//尾插
void SeqListPushBack(SL*ps, SLDateType x);//打印数据
void SeqListprint(SL* ps);//头插
void SeqListPushFront(SL* ps, SLDateType x);//尾删
void SeqListPopBack(SL* ps);//头删
void SeqListPopFront(SL* ps);//在数组里面找一个数字,找到就返回下标,否则就是返回-1
int SeqListfind(SL* ps, SLDateType x);//在指定的位置插入一个数字
void SeqListInsert(SL* ps, int pos, SLDateType x);//pos是指定的下标位置//在指定位置删除一个数字
void SeqListErase(SL* ps, int pos);//最后销毁空间
void SeqlistDestory(SL* ps);

2.SeqList.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//检查容量
void SeqListCheckCapacity(SL* ps)
{if (ps->size == ps->Capacity)//初始化都为0,肯定if成立进入语句{                              //这里一定要写成==,因为这里判断语句int NewCapacity = ps->Capacity == 0 ? 4 : ps->Capacity * 2;//这里使用一个三目操作符SLDateType* temp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * NewCapacity);if (temp == NULL)//如果开辟空间错误{printf("realloc is error\n");exit(-1);//退出程序}ps->a = temp;ps->Capacity = NewCapacity;}
}//初始化顺序表
void SeqListInit(SL*ps)
{ps->a = NULL;//先将动态数组置为空指针ps->size = ps->Capacity = 0;//有效个数和容量大小都设为0
}//尾插
void SeqListPushBack(SL* ps, SLDateType x)
{SeqListCheckCapacity(ps);//检查容量SeqListInsert(ps, ps->size, x);//调用插入函数来复用头插,头插就是在0的位置进行插入
}//打印函数
void SeqListprint(SL* ps) 
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//头插
void SeqListPushFront(SL* ps, SLDateType x)
{SeqListCheckCapacity(ps);//检查容量SeqListInsert(ps, 0, x);//调用插入函数来复用头插,头插就是在0的位置进行插入
}
//尾删
void SeqListPopBack(SL* ps)
{assert(ps->size > 0);//这里断言一下,如果ps->size小于0之后,直接报错ps->size--;
}
//头删
void SeqListPopFront(SL* ps)
{int start = 0;while (start < ps->size){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}
//在数组里面找一个数字,找到就返回下标,否则就是返回-1
int SeqListfind(SL* ps, SLDateType x)
{int i = 0;while (i < ps->size){if (ps->a[i] == x){return i;}i++;}return -1;
}
//在指定的位置插入一个数字
void  SeqListInsert(SL* ps, int pos, SLDateType x)//pos是指定的下标位置
{SeqListCheckCapacity(ps);//检查容量int end = ps->size-1;while (end>=pos){ps->a[end+1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
//在指定位置删除一个数字
void SeqListErase(SL* ps, int pos)
{int end = pos;while (end < ps->size){ps->a[end] = ps->a[end + 1];end++;}ps->size--;
}
//最后销毁空间
void SeqlistDestory(SL* ps)
{free(ps->a = NULL);ps->size = ps->Capacity = 0;
}

3.test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"SL sl;SL* ps;
void test()
{printf("\n*********************************\n");printf("1.尾插  2.头插\n");printf("3.尾删  4.头删\n");printf("5.指定删 6.指定插\n");printf("7.找一个数  -1.退出\n");printf("**********************************\n");printf("请选择你要进行的操作:>\n");
}
void Menutest()
{SL sl;SeqListInit(&sl);int x = 0;int y = 0;int input = 0;while (input != -1){test();//每一次输入结束了,都会再次打印菜单scanf("%d", &input);switch (input){case 1:{printf("请你输入要尾插的数字,以-1结束:");scanf("%d", &x);while (x != -1)//还是有缺陷,不能插入-1{SeqListPushBack(&sl, x);scanf("%d", &x);}printf("尾插之后为:");SeqListprint(&sl);break;}case 2:{printf("请你输入要头插的数字,以-1结束:");scanf("%d", &x);while (x != -1){SeqListPushFront(&sl, x);scanf("%d", &x);}printf("尾插之后为:");SeqListprint(&sl);break;}case 3:{SeqListPopBack(&sl);printf("尾删之后为:");SeqListprint(&sl);break;}case 4:{SeqListPopFront(&sl);printf("头删之后为:");SeqListprint(&sl);break;}case 5:{printf("请你输入要删数字的下标:");scanf("%d", &x);SeqListErase(&sl, x);printf("删除数字后:");SeqListprint(&sl);break;}case 6:{printf("请你输入要插数字的下标和数字:");scanf("%d %d", &x, &y);SeqListInsert(&sl, x, y);printf("插入数字后:");SeqListprint(&sl);break;}case 7:{printf("请你输入你要找的数字:");scanf("%d", &x);int ret = SeqListfind(&sl, x);if (ret != -1){printf("查找的坐标为:");printf("%d", ret);}break;}default:printf("选择错误,请重新输入");break;}}
}
int main()
{Menutest();SeqlistDestory(&sl);return 0;
}

相关文章:

【数据结构】万字超详解顺序表(比细狗还细)

我这个人走得很慢&#xff0c;但是我从不后退。 ——亚伯拉罕林肯 目录 一.什么是线性表&#xff1f; 二.什么是顺序表&#xff1f; 三.接口函数的实现 1.创建工程 2.构造顺序表 3.初始化顺序表 3.初始化顺序表 4.顺序表的尾插 5.顺序…...

yolov5 剪枝、蒸馏、压缩、量化

文章大纲 剪枝推理优化YOLOv5 剪枝可能出现的问题参考文献与学习路径考察神经网络时期重要的激活函数sigmoid和tanh,它们有一个特点,即输入值较大或者较小的时候,其导数变得很小,而在训练阶段(详见1.2.3节),需要求取多个导数值,并将每层得到的导数值相乘,这样一旦层数…...

如何用python代码,更改照片尺寸,以及更换照片底色

前言 python浅浅替代ps&#xff1f;如何用代码来p证件照并且更换底色&#xff1f; 唉&#xff0c;有个小姐姐给我扔了张照片&#xff0c;叫我帮忙给她搞成证件照的尺寸还得换底色&#xff0c;她说自己忙的很 可惜电脑上没有ps只有pycharm&#xff0c;没得办法只能来试试看代…...

【pygame游戏】Python实现蔡徐坤大战篮球游戏【附源码】

前言 话说在前面&#xff0c;我不是小黑子~&#x1f60f; 本文章纯属技术交流~娱乐 前几天我获得了一个坤坤打篮球的游戏&#xff0c;也给大家分享一下吧~ 好吧&#xff0c;其实并不是这样的游戏&#xff0c;往下慢慢看吧。 准备工作 开发环境 Python版本&#xff1a;3.7.8 …...

通过指针引用字符串详解,以及字符指针变量和字符数组的比较

在平常的案例中已大量地使用了字符串&#xff0c;如在 printf函数中输出一个字符串。这些字符串都是以直接形式 (字面形式) 给出的&#xff0c;在一对双引号中包含若干个合法的字符。在本节中将介绍使用字符串的更加灵活方便的方法&#xff1a;通过指针引用字符串。 目录 一、…...

Vue基本整合(一)

NPM安装npm是node的包管理工具https://nodejs.org/en/脚手架安装npm i -g vue/clihttps://registry.npmjs.org/vue浏览器插件https://devtools.vuejs.org/guide/installation.html#chromehttps://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhble…...

C++编程之 万能引用

万能引用是一种可以同时接受左值或右值的引用&#xff0c;它的形式是T&&&#xff0c;其中T是一个模板参数。万能引用不是C的一个新特性&#xff0c;而是利用了模板类型推导和引用折叠的规则来实现的功能。 模板类型推导 模板类型推导是指在调用一个模板函数时&#x…...

【JavaScript速成之路】JavaScript内置对象--数组对象

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言数组对象1&#xff0c;数组类型检测2&#xff0c;数组元素增删3&#xff0c;…...

【华为机试真题详解 Python实现】最差产品奖【2023 Q1 | 100分】

文章目录 前言题目描述输入描述输出描述示例 1题目解析参考代码前言 《华为机试真题详解》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。 如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议! 本文解法非最优解(即非性能…...

[算法] 二分查找

package com.guigu.search;import java.util.ArrayList; import java.util.Arrays;/*** author: guorui fu* versiion: 1.0* 二分查找 直接适用于已经排序完成的数组*/ public class BinarySearch {public static void main(String[] args) {int arr[] {1,8,8,89,101,1234};Ar…...

HTML面经

1.src与href的区别 src用于替换当前元素&#xff0c;如script标签&#xff0c;img标签等。当html解析到这些标签时&#xff0c;会暂停解析&#xff0c;将指定的资源下载下来&#xff0c;嵌入到所在位置内。href的话则是一个当前页面与引用资源之间的链接&#xff0c;如link标签…...

我的十年编程路 2021年篇

慢慢地&#xff0c;时光走过了8个年头&#xff0c;来到2021年。 站在2021年&#xff0c;回望8年的过往&#xff0c;没有大的起伏和波澜。或许是上天的眷顾&#xff0c;我的事业发展一直都很顺利。当然&#xff0c;弯路也走过一些&#xff0c;而且工作其实挺辗转的&#xff0c;…...

ElasticSearch 8 学习笔记总结(七)

感觉这些东西没必要认真学&#xff0c;了解一下&#xff0c;工作用到再学。 文章目录一、ES8 EQL 介绍二、ES8 EQL基本操作 与 安全检测三、ES SQL操作四、ES SQL与DSL的关系五、ES 常用的SQL操作六、ES datagrip配置ES七、ES8 自然语言处理 NLP八、ES8 性能优化 之 缓存九、ES…...

【云原生】Docker 网络模式详解、容器间网络通信

当项目大规模使用 Docker 时&#xff0c;容器通信的问题也就产生了。要解决容器通信问题&#xff0c;必须先了解很多关于网络的知识。Docker 作为目前最火的轻量级容器技术&#xff0c;有很多令人称道的功能&#xff0c;也有着很多不完善的地方&#xff0c;网络方面就是 Docker…...

Java开发 - 布隆过滤器初体验

目录 前言 布隆过滤器 什么是布隆过滤器 布隆过滤器的作用 布隆过滤器原理 怎么设计布隆过滤器 布隆过滤器使用案例 安装布隆过滤器 添加依赖 添加配置 添加工具类 添加测试代码 简单测试 特别提醒​​​​​​​ 结语 前言 前面三篇&#xff0c;已经把消息队列…...

【计算机组成原理 - 第一章】计算机系统概论(完结)

本章参考王道考研相关课程&#xff1a; 【2021版】1.2.1_计算机硬件的基本组成_哔哩哔哩_bilibili 【2021版】1.2.2_认识各个硬件部件_哔哩哔哩_bilibili 【2021版】1.2.3_计算机系统的层次结构_哔哩哔哩_bilibili 【2021版】1.3_计算机的性能指标_哔哩哔哩_bilibili 目录 一、…...

C++类与对象(下)【详析】

类与对象&#xff08;下&#xff09; 目录类与对象&#xff08;下&#xff09;一、再谈构造函数1.构造函数体赋值2.初始化列表定义&#xff1a;注意点&#xff1a;总结&#xff1a;3.explicit关键字引入&#xff1a;explicit&#xff1a;二、 static成员回顾&#xff1a;static…...

exe反编译为.py文件

介绍公司以前的一个exe包&#xff0c;我们需要查看里面python源码&#xff0c;但是以前的py源码文件找不到&#xff0c;所以只能反编译&#xff0c;介绍一下反编译的过程。首先准备&#xff1a;pyinstxtractor.py这个文件&#xff0c;网上很多&#xff0c;自己下载准备查看二进…...

38 openEuler搭建FTP服务器-FTP总体介绍

文章目录38 openEuler搭建FTP服务器-FTP总体介绍38.1 FTP简介38.2 FTP使用到的端口38.3 vsftpd简介38 openEuler搭建FTP服务器-FTP总体介绍 38.1 FTP简介 FTP&#xff08;File Transfer Protocol&#xff09;即文件传输协议&#xff0c;是互联网最早的传输协议之一&#xff0…...

三天吃透操作系统面试八股文

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...