【数据结构】万字超详解顺序表(比细狗还细)
我这个人走得很慢,但是我从不后退。 ——亚伯拉罕·林肯

目录
一.什么是线性表?
二.什么是顺序表?
三.接口函数的实现
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;
}
相关文章:
【数据结构】万字超详解顺序表(比细狗还细)
我这个人走得很慢,但是我从不后退。 ——亚伯拉罕林肯 目录 一.什么是线性表? 二.什么是顺序表? 三.接口函数的实现 1.创建工程 2.构造顺序表 3.初始化顺序表 3.初始化顺序表 4.顺序表的尾插 5.顺序…...
yolov5 剪枝、蒸馏、压缩、量化
文章大纲 剪枝推理优化YOLOv5 剪枝可能出现的问题参考文献与学习路径考察神经网络时期重要的激活函数sigmoid和tanh,它们有一个特点,即输入值较大或者较小的时候,其导数变得很小,而在训练阶段(详见1.2.3节),需要求取多个导数值,并将每层得到的导数值相乘,这样一旦层数…...
如何用python代码,更改照片尺寸,以及更换照片底色
前言 python浅浅替代ps?如何用代码来p证件照并且更换底色? 唉,有个小姐姐给我扔了张照片,叫我帮忙给她搞成证件照的尺寸还得换底色,她说自己忙的很 可惜电脑上没有ps只有pycharm,没得办法只能来试试看代…...
【pygame游戏】Python实现蔡徐坤大战篮球游戏【附源码】
前言 话说在前面,我不是小黑子~😏 本文章纯属技术交流~娱乐 前几天我获得了一个坤坤打篮球的游戏,也给大家分享一下吧~ 好吧,其实并不是这样的游戏,往下慢慢看吧。 准备工作 开发环境 Python版本:3.7.8 …...
通过指针引用字符串详解,以及字符指针变量和字符数组的比较
在平常的案例中已大量地使用了字符串,如在 printf函数中输出一个字符串。这些字符串都是以直接形式 (字面形式) 给出的,在一对双引号中包含若干个合法的字符。在本节中将介绍使用字符串的更加灵活方便的方法:通过指针引用字符串。 目录 一、…...
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++编程之 万能引用
万能引用是一种可以同时接受左值或右值的引用,它的形式是T&&,其中T是一个模板参数。万能引用不是C的一个新特性,而是利用了模板类型推导和引用折叠的规则来实现的功能。 模板类型推导 模板类型推导是指在调用一个模板函数时&#x…...
【JavaScript速成之路】JavaScript内置对象--数组对象
📃个人主页:「小杨」的csdn博客 🔥系列专栏:【JavaScript速成之路】 🐳希望大家多多支持🥰一起进步呀! 文章目录前言数组对象1,数组类型检测2,数组元素增删3,…...
【华为机试真题详解 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用于替换当前元素,如script标签,img标签等。当html解析到这些标签时,会暂停解析,将指定的资源下载下来,嵌入到所在位置内。href的话则是一个当前页面与引用资源之间的链接,如link标签…...
我的十年编程路 2021年篇
慢慢地,时光走过了8个年头,来到2021年。 站在2021年,回望8年的过往,没有大的起伏和波澜。或许是上天的眷顾,我的事业发展一直都很顺利。当然,弯路也走过一些,而且工作其实挺辗转的,…...
ElasticSearch 8 学习笔记总结(七)
感觉这些东西没必要认真学,了解一下,工作用到再学。 文章目录一、ES8 EQL 介绍二、ES8 EQL基本操作 与 安全检测三、ES SQL操作四、ES SQL与DSL的关系五、ES 常用的SQL操作六、ES datagrip配置ES七、ES8 自然语言处理 NLP八、ES8 性能优化 之 缓存九、ES…...
【云原生】Docker 网络模式详解、容器间网络通信
当项目大规模使用 Docker 时,容器通信的问题也就产生了。要解决容器通信问题,必须先了解很多关于网络的知识。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,也有着很多不完善的地方,网络方面就是 Docker…...
Java开发 - 布隆过滤器初体验
目录 前言 布隆过滤器 什么是布隆过滤器 布隆过滤器的作用 布隆过滤器原理 怎么设计布隆过滤器 布隆过滤器使用案例 安装布隆过滤器 添加依赖 添加配置 添加工具类 添加测试代码 简单测试 特别提醒 结语 前言 前面三篇,已经把消息队列…...
【计算机组成原理 - 第一章】计算机系统概论(完结)
本章参考王道考研相关课程: 【2021版】1.2.1_计算机硬件的基本组成_哔哩哔哩_bilibili 【2021版】1.2.2_认识各个硬件部件_哔哩哔哩_bilibili 【2021版】1.2.3_计算机系统的层次结构_哔哩哔哩_bilibili 【2021版】1.3_计算机的性能指标_哔哩哔哩_bilibili 目录 一、…...
C++类与对象(下)【详析】
类与对象(下) 目录类与对象(下)一、再谈构造函数1.构造函数体赋值2.初始化列表定义:注意点:总结:3.explicit关键字引入:explicit:二、 static成员回顾:static…...
exe反编译为.py文件
介绍公司以前的一个exe包,我们需要查看里面python源码,但是以前的py源码文件找不到,所以只能反编译,介绍一下反编译的过程。首先准备:pyinstxtractor.py这个文件,网上很多,自己下载准备查看二进…...
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(File Transfer Protocol)即文件传输协议,是互联网最早的传输协议之一࿰…...
三天吃透操作系统面试八股文
本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~ Github地址:https://github.com/…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...
