【数据结构】万字深入浅出讲解顺序表(附原码 | 超详解)

news2024/11/17 12:20:40

在这里插入图片描述

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:C语言实现数据结构
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

文章目录

  • 前言
  • 一、线性表概念
    • 1.1线性表
  • 二、顺序表实现
    • 2.1概念及结构
    • 2.2 接口的布局
    • 2.3接口的实现
      • SeqList.h的代码
      • SeqList.c 的代码
  • 三、完整代码
  • 总结


前言

在这里插入图片描述
这几天看了数据结构的顺序表这一节,真的收获很大,第一次看没有动手敲代码就是感觉学了和没学一样,今天也是从新又看了一遍,并且边学边敲代码,终于算是非常理解顺序表这个东西了,今天就把我所学到的知识给大家分享一下。


提示:以下是本篇文章正文内容,下面案例可供参考

一、线性表概念

1.1线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使
用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,
线性表在物理上存储时,通常以数组和链式结构的形式存储。

在这里插入图片描述

二、顺序表实现

2.1概念及结构

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

顺序表一般可以分为:

  • 静态顺序表:使用定长数组存储。
  • 动态顺序表:使用动态开辟的数组存储.

以下是静态顺序表:

#pragma once//防止被重复的包含 

#define N 100
typedef int SQDataType;

typedef struct SeqList
{
	SQDataType a[N];
	SQDataType size; //有效数据 
}SL;
//增删查改等接口函数 

//对于结构体的定义typedef struct SeqList SL;

//静态顺序表
//问题:给少了不够用,给多了用不完浪费,不能灵活控制

由于静态顺序表无法伸缩变换数组,所以今天着重讲解动态的顺序表

动态顺序表的实现:

//#pragma once 
//#define N 10 对于动态线性表这个就没有用了 
typedef int SQDataType;

typedef struct SeqList
{
	SQDataType* a;
	int size;	  //有效数据的个数 
	int capacity; //容量 
}SL;

2.2 接口的布局

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大
了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表根据需要动态
的分配空间大小,所以下面我们实现动态顺序表。

我们需要的工程文件

  • SeqList.h:用于存放函数声明、包含头文件、定义宏等等。
  • test.c:用于写程序整体执行逻辑等。
  • SeqList.c:用于写函数定义,写函数实现等。

2.3接口的实现

SeqList.h的代码

#include<string.h>
#include<stdio.h>//printf
#include<stdlib.h>//realloc 
#include<assert.h>//断言 

typedef int SQDataType; //方便修改数据 

typedef struct SeqList //重命名方便书写 
{
	SQDataType* a;
	int size;	  //有效数据的个数 
	int capacity; //容量 
}SL;


//初始化与销毁:
void SeqListInit(SL* ps);//初始化顺序表 
void SeqListCheckCapcity(SL* ps)//创建新空间---扩容
void SeqListDestory(SL* ps)//销毁空间 

//顺序表的插入操作---头插,尾插,任意插
void SeqListPushBack(SL* ps,SQDataType x);//顺序表尾插 o(1) 
void SeqListPushFront(SL* ps,SQDataType x);//顺序表头插  o(n)
void SeqListInsert(SL* ps,int pos,SQDataType x) //在顺序表指定下标位置插入数据 

//顺序表的删除操作---头删,尾删,任意删
void SeqListPopBack(SL* ps);//顺序表尾删 o(1)
void SeqListPopfront(SL* ps);//顺序表头删 o(n)
void SeqListErase(SL* ps,int pos) //顺序表任意下标删除 

//顺序表的查找、打印、寻找
int SeqListFind(SL* ps,SQDataType x) //顺序表查找下标 
int  SeqListModity(SL* ps,int pos,SQDataType x)//修改指定下标位置的数据 
void SeqListPrint(SL* ps)//打印顺序表元素 

SeqList.c 的代码

这里就是实现上述的函数的代码啦~

  • 初始化顺序表
void SeqListInit(SL* ps)
{
	aseert(ps)//断言 
	//初始化
	ps->a=NULL;//设置为空 
	ps->size=0;//设置为0 
	ps->capacity=0;//设置为0 
}
  • 检查顺序表容量和扩容
    如果顺序表空间足够,那么不需要扩容,通过相关操作插入数据,如果空间不足或者根本没有空间,那么就得扩容。

当顺序表没有空间时,我们开辟四个空间(至少为1个空间);当顺序表空间不足,我们将当前空间扩大为两倍

void SeqListCheckCapcity(SL* ps)
{
	assert(ps!= NULL);  //断言
	if(ps->size==ps->capacity)
	{
		int newcapacity=ps->capacity==0?4:ps->capacity*2;//如果是0就改为4,不是0就扩大二倍 
		SQDataType* tmp=(SQDataType*)realloc(ps->a,newcapacity*sizeof(SQDataType));
		if(tmp==NULL)
		{
			printf("realloc fail\n");//扩容失败 
			exit(-1);
		}
		else //扩容成功 
		{
			ps->a=tmp;//新的数组对吧 
			ps->capacity =newcapacity;//有效的容量 
		}
	}
}
  • 销毁顺序表
void SeqListDestory(SL* ps)//销毁 
{
	assert(ps != NULL);  //断言
	free(ps->a);//释放动态开辟的空间
	ps->a=NULL;//置空
	ps->capacity=0;//数据个数置0
	ps->size=0;//空间容量大小置0
}
  • 顺序表尾插
void SeqListPushBack(SL* ps,SQDataType x)//尾插
{
	//满了就要扩容 
//	if(ps->size==ps->capacity)
//	{
//		int newcapacity=ps->capacity==0?4:ps->capacity*2;
//		SQDataType* tmp=(SQDataType*)realloc(ps->a,newcapacity*2*sizeof(SQDataType));
//		if(tmp==NULL)
//		{
//			printf("realloc fail\n");
//			exit(-1);
//		}
//		else 
//		{
//			ps->a=tmp;//新的数组对吧 
//			ps->capacity = newcapacity;//有效的容量 
//		}
//	}	
	SeqListCheckCapcity(ps);//扩容函数 
	ps->a[ps->size]=x;//设置为要改的数x 
	ps->size++;//让数组长度增加 
}

测试:

void TestSeqList1()
{
	SL s1;
	SeqListInit(&s1); //初始化顺序表
	SeqListPushBack(&s1,1);
	SeqListPushBack(&s1,2);
	SeqListPushBack(&s1,3);
	SeqListPushBack(&s1,4);
	SeqListPushBack(&s1,5);
	SeqListPushBack(&s1,6);
	SeqListPushBack(&s1,7);
	SeqListPushBack(&s1,8);
	SeqListPushBack(&s1,9);
	SeqListPushBack(&s1,10);
	SeqListPushBack(&s1,11);
	SeqListPrint(&s1);//打印顺序表:下面实现
	//销毁顺序表:
	SeqListDestory(&s1);
}
int main()
{
	TestSeqList1();
	//TestSeqList2();
	return 0;
}

在这里插入图片描述

  • 顺序表尾删
    每次都在最后一个元素之后插入新的元素
void SeqListPopBack(SL* ps)//尾删 
{
	assert(ps->size>0);//断言 
	
	//ps->a[ps->size-1]=0;
	ps->size--;//数组减少 
}
void TestSeqList2()
{
	SL s1;
	SeqListInit(&s1);
	SeqListPushFront(&s1,1);
	SeqListPushFront(&s1,2);
	SeqListPushFront(&s1,3);
	SeqListPushFront(&s1,4);
	SeqListPushFront(&s1,5);
	SeqListPushFront(&s1,6);
	SeqListPopBack(&s1);
	SeqListPopBack(&s1);
	SeqListPopfront(&s1);
	SeqListPrint(&s1);
}

int main()
{
	//TestSeqList1();
	TestSeqList2();
	return 0;
}

在这里插入图片描述

  • 顺序表头插
    每次都在头结点之后插入新元素,头插法较为重要,当遇到链表的逆置操作时,可以使用头插法实现
void SeqListPushFront(SL* ps,SQDataType x)//头插 
{
	//1.初始条件
	//2.结束条件
	//3.迭代过程 
	
	//还是要考虑增容的情况
	SeqListCheckCapcity(ps);//扩容 
	int end=ps->size-1;//找到end指针 
	while(end>=0) //循环右移 
	{
		ps->a[end+1]=ps->a[end];
		--end;
	}
	ps->a[0]=x;//插入 
	ps->size++;//数组加大 
}

在这里插入图片描述
实现:

void TestSeqList2()
{
	SL s1;
	SeqListInit(&s1);
	SeqListPushFront(&s1,1);
	SeqListPushFront(&s1,2);
	SeqListPushFront(&s1,3);
	SeqListPushFront(&s1,4);
	SeqListPushFront(&s1,5);
	SeqListPushFront(&s1,6);
	SeqListPopBack(&s1);
	SeqListPopBack(&s1);
	SeqListPopfront(&s1);
	SeqListPrint(&s1);
}

int main()
{
	//TestSeqList1();
	TestSeqList2();
	return 0;
}

在这里插入图片描述

  • 顺序表头删
void SeqListPopfront(SL* ps)//头删
{
	assert(ps->size>0);
	
	int start=1;
	while(start<ps->size)
	{
		ps->a[start-1]=ps->a[start];
		++start;
	}
	ps->size--;
}

在这里插入图片描述

  • 打印顺序表
void SeqListPrint(SL* ps)
{
	for(int i=0;i<ps->size;++i)
	{
		printf("%d ",ps->a[i]);
	}
	printf("\n");
}
  • 顺序表指定下标位置插入数据

插入操作,在表L中的第i个位置上插入指定元素

想要在第i个位置上插入元素,那么就要找到第i − 1 个结点,然后将新结点插入其后面

void SeqListInsert(SL* ps,int pos,SQDataType x) //任意插入 
{
	assert(pos<ps->size);
	SeqListCheckCapcity(ps);
	
	int end=ps->size-1;
	while(end>=pos)
	{
		ps->a[end+1]=ps->a[end];
		--end;
	}
	
	ps->a[pos]=x;
	ps->size++;
}
  • 顺序表任意下标删除

但是,使用这个算法有个问题,如果p是最后一个结点,那么当程序执行到p->data = p->next->data这一句时,会出现空指针的错误,所以只能从表头开始依次寻找p的前驱

void SeqListErase(SL* ps,int pos) //任意删除 
{
	assert(pos<ps->size); 
	
	int start=pos+1;
	while(start<ps->size)
	{
		ps->a[start-1]=ps->a[start];
		++start;
	}
	ps->size--;
}
  • 顺序表查找下标
    按位查找操作。获取表L中第i个位置的元素的值
int SeqListFind(SL* ps,SQDataType x) //查找 
{
	for(int i=0;i<ps->size;++i)
	{
		if(ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}
  • 改指定下标位置的数据
int  SeqListModity(SL* ps,int pos,SQDataType x)//修改位置的值 
{
	assert(pos<ps->size);
	ps->a[pos]=x;
}

三、完整代码

SeqList.h

#include<string.h>
#include<stdio.h>//printf
#include<stdlib.h>//realloc 
#include<assert.h>//断言 

typedef int SQDataType; //方便修改数据 

typedef struct SeqList //重命名方便书写 
{
	SQDataType* a;
	int size;	  //有效数据的个数 
	int capacity; //容量 
}SL;


void SeqListInit(SL* ps);//初始化顺序表 
void SeqListCheckCapcity(SL* ps)//创建新空间---扩容
void SeqListDestory(SL* ps)//销毁空间 


void SeqListPushBack(SL* ps,SQDataType x);//顺序表尾插 o(1) 
void SeqListPushFront(SL* ps,SQDataType x);//顺序表头插  o(n)
void SeqListInsert(SL* ps,int pos,SQDataType x) //在顺序表指定下标位置插入数据 

void SeqListPopBack(SL* ps);//顺序表尾删 o(1)
void SeqListPopfront(SL* ps);//顺序表头删 o(n)
void SeqListErase(SL* ps,int pos) //顺序表任意下标删除 

int SeqListFind(SL* ps,SQDataType x) //顺序表查找下标 
int  SeqListModity(SL* ps,int pos,SQDataType x)//修改指定下标位置的数据 
void SeqListPrint(SL* ps)//打印顺序表元素 

SeqList.c:


//void SeqListInit(SL* ps);
//{
//	//初始化
//	memset(s1.a,0,sizeof(SQDataType)*N);
//	s1.size=0;
//}
//
//void SeqListPushBack(SL* ps,SQDataType x);//尾插
//{
//	if(ps->size>=N)
//	{
//		printf("SeqList is Full\n");
//		return;
//	}
//	
//	ps->a[ps->size]=x;
//	ps->size++;
//}
//以上就是静态 
//------------------------------------------------
//下面实现动态

 
void SeqListInit(SL* ps);
{
	//初始化
	ps->a=NULL;
	ps->size=0;
	ps->capacity=0;//开始如果是一个0的话,那么扩容就会失败 
}

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

void SeqListPushBack(SL* ps,SQDataType x);//尾插
{
	//满了就要扩容 
//	if(ps->size==ps->capacity)
//	{
//		int newcapacity=ps->capacity==0?4:ps->capacity*2;
		SQDataType* tmp=(SQDataType*)realloc(ps->a,ps->capacity*2*sizeof(SQDataType));
//		SQDataType* tmp=(SQDataType*)realloc(ps->a,ps->newcapacity*2*sizeof(SQDataType));
//		if(tmp==NULL)
//		{
//			printf("realloc fail\n");
//			exit(-1);
//		}
//		else 
//		{
//			ps->a=tmp;//新的数组对吧 
//			ps->capacity =newcapacity;//有效的容量 
//		}
//	}	
	SeqListCheckCapcity(&ps);
	ps->a[ps->size]=x;
	ps->size++;
}

void SeqListDestory(SL* ps)//销毁 
{
	free(ps->a);
	ps->a=NULL;
	ps->capacity=0;
	ps->size=0;
}



void SeqListCheckCapcity(SL* ps)
{
	if(ps->size==ps->capacity)
	{
		int newcapacity=ps->capacity==0?4:ps->capacity*2;
		SQDataType* tmp=(SQDataType*)realloc(ps->a,newcapacity*sizeof(SQDataType));
		if(tmo==NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else 
		{
			ps->a=tmp;//新的数组对吧 
			ps->capacity =newcapacity;//有效的容量 
		}
	}
}

void SeqListPushFront(SL* ps,SQDataType x);//头插 
{
	//1.初始条件
	//2.结束条件
	//3.迭代过程 
	
	//还是要考虑增容的情况
	SeqListCheckCapcity(&ps);
	int end=ps->size-1;
	while(end>=0)
	{
		ps->a[end+1]=ps->a[end];
		--end;
	}
	ps->a[0]=x;
	ps->size++;
}

void SeqListPopBack(SL* ps)//尾删 
{
	assert(ps->size>0)
	
	//ps->a[ps->size-1]=0;
	ps->size--;
}

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

void SeqListInsert(SL* ps,int pos,SQDataType x) //任意插入 
{
	assert(pos<ps->size);
	SeqListCheckCapcity(&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) //任意删除 
{
	assert(pos<ps->size)
	
	int start=pos+1;
	while(start<ps->size)
	{
		ps->a[start-1]=ps->a[start];
		++start;
	}
	ps->size--;
}

int SeqListFind(SL* ps,SQDataType x) //查找 
{
	for(int i=0;i<ps->size;++i)
	{
		if(ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

int  SeqListModity(SL* ps,int pos,SQDataType x)//修改位置的值 
{
	assert(pos<ps->size);
	ps->a[pos]=x;
}

test.c

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//#pragma once 
//#define N 10 对于动态线性表这个就没有用了 
typedef int SQDataType;

typedef struct SeqList
{
	SQDataType* a;
	int size;	  //有效数据的个数 
	int capacity; //容量 
}SL;

void SeqListInit(SL* ps)
{
	//
	//初始化
	ps->a=NULL;//设置为空 
	ps->size=0;//设置为0 
	ps->capacity=0;//设置为0 
}

void SeqListCheckCapcity(SL* ps)
{
	assert(ps!= NULL);  //断言
	if(ps->size==ps->capacity)
	{
		int newcapacity=ps->capacity==0?4:ps->capacity*2;//如果是0就改为4,不是0就扩大二倍 
		SQDataType* tmp=(SQDataType*)realloc(ps->a,newcapacity*sizeof(SQDataType));
		if(tmp==NULL)
		{
			printf("realloc fail\n");//扩容失败 
			exit(-1);
		}
		else //扩容成功 
		{
			ps->a=tmp;//新的数组对吧 
			ps->capacity =newcapacity;//有效的容量 
		}
	}
}

void SeqListPushBack(SL* ps,SQDataType x)//尾插
{
	//满了就要扩容 
//	if(ps->size==ps->capacity)
//	{
//		int newcapacity=ps->capacity==0?4:ps->capacity*2;
//		SQDataType* tmp=(SQDataType*)realloc(ps->a,newcapacity*2*sizeof(SQDataType));
//		if(tmp==NULL)
//		{
//			printf("realloc fail\n");
//			exit(-1);
//		}
//		else 
//		{
//			ps->a=tmp;//新的数组对吧 
//			ps->capacity = newcapacity;//有效的容量 
//		}
//	}	
	SeqListCheckCapcity(ps);//扩容函数 
	ps->a[ps->size]=x;//设置为要改的数x 
	ps->size++;//让数组长度增加 
}

void SeqListPushFront(SL* ps,SQDataType x)//头插 
{
	//1.初始条件
	//2.结束条件
	//3.迭代过程 
	
	//还是要考虑增容的情况
	SeqListCheckCapcity(ps);//扩容 
	int end=ps->size-1;//找到end指针 
	while(end>=0) //循环右移 
	{
		ps->a[end+1]=ps->a[end];
		--end;
	}
	ps->a[0]=x;//插入 
	ps->size++;//数组加大 
}

void SeqListPopBack(SL* ps)//尾删 
{
	assert(ps->size>0);//断言 
	
	//ps->a[ps->size-1]=0;
	ps->size--;//数组减少 
}

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

void SeqListInsert(SL* ps,int pos,SQDataType x) //任意插入 
{
	assert(pos<ps->size);
	SeqListCheckCapcity(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) //任意删除 
{
	assert(pos<ps->size); 
	
	int start=pos+1;
	while(start<ps->size)
	{
		ps->a[start-1]=ps->a[start];
		++start;
	}
	ps->size--;
}

int SeqListFind(SL* ps,SQDataType x) //查找 
{
	for(int i=0;i<ps->size;++i)
	{
		if(ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

int  SeqListModity(SL* ps,int pos,SQDataType x)//修改位置的值 
{
	assert(pos<ps->size);
	ps->a[pos]=x;
}

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


void TestSeqList1()
{
	SL s1;
	SeqListInit(&s1);
	SeqListPushBack(&s1,1);
	SeqListPushBack(&s1,2);
	SeqListPushBack(&s1,3);
	SeqListPushBack(&s1,4);
	SeqListPushBack(&s1,5);
	SeqListPushBack(&s1,6);
	SeqListPushBack(&s1,7);
	SeqListPushBack(&s1,8);
	SeqListPushBack(&s1,9);
	SeqListPushBack(&s1,10);
	SeqListPushBack(&s1,11);
	SeqListPrint(&s1);
}

void TestSeqList2()
{
	SL s1;
	SeqListInit(&s1);
	SeqListPushFront(&s1,1);
	SeqListPushFront(&s1,2);
	SeqListPushFront(&s1,3);
	SeqListPushFront(&s1,4);
	SeqListPushFront(&s1,5);
	SeqListPushFront(&s1,6);
	SeqListPopBack(&s1);
	SeqListPopBack(&s1);
	SeqListPopfront(&s1);
	SeqListPrint(&s1);
}

int main()
{
	//TestSeqList1();
	TestSeqList2();
	return 0;
}

总结

  今天学习了线性表的知识,初次写数据结构的知识,给我的感觉就是,学三遍不如手敲代码一遍来的实在,所以数据结构的学习我将多画图,多敲代码来学习,希望大家吸取经验和我一起学习数据结构,为后面打比赛刷题打下坚实基础。

  我是夏目浅石,希望和你一起学习进步,刷题无数!!!希望各位大佬能一键三连支持一下博主,hhhh~我们下期见喽
在这里插入图片描述
如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力! \textcolor{9c81c1}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{ed7976}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{98c091}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能矿山电子封条系统 YOLOv5

智能矿山电子封条系统通过yolov5深度学习技术&#xff0c;对现场画面进出口以及主要的井口等重要地方对矿井人员变化、生产作业执勤状态及出入井人员等状况实时监控分析监测。我们使用YOLO(你只看一次)算法进行对象检测。YOLO是一个聪明的卷积神经网络(CNN)&#xff0c;用于实时…

Google AIY Vision Kit安装及国内配置

Google AIY Vision Kit安装及国内配置1. AIY Vision Kit组装环节Step 1&#xff1a;收集其他附件选择1&#xff1a;使用AIY项目应用程序选择2&#xff1a;使用显示器、鼠标和键盘Step 2&#xff1a;检查硬件清单Step 3&#xff1a;构建AIY Vision KitStep 3.1&#xff1a;获取最…

旺店通·企业奇门和用友BIP接口打通对接实战

旺店通企业奇门和用友BIP接口打通对接实战接通系统&#xff1a;旺店通企业奇门旺店通是北京掌上先机网络科技有限公司旗下品牌&#xff0c;国内的零售云服务提供商&#xff0c;基于云计算SaaS服务模式&#xff0c;以体系化解决方案&#xff0c;助力零售企业数字化智能化管理升级…

Mac和Windows局域网互传文件iPhone和Windows局域网互传文件

生活中&#xff0c;我们可以通过微信和QQ或网盘等等传输工具进而实现文件互传&#xff0c;但是面临一个问题&#xff0c;大文件无法上传&#xff0c;而且受到网速的限制等诸多因素影响&#xff0c;如今我们可以通过局域网进行实现文件互传&#xff0c;进而改变此种囧境。 首先在…

17道Redis 面试题

Redis 持久化机制缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题热点数据和冷数据是什么Memcache与Redis的区别都有哪些&#xff1f;单线程的redis为什么这么快redis的数据类型&#xff0c;以及每种数据类型的使用场景&#xff0c;Redis 内部结构redis的过期策略以及…

KVM安装部署 | 举例安装虚机Windows2012R2

目录 1、基础环境准备 2、KVM的安装 3、开启服务 4、开启图形化界面 5、也可以通过浏览器管理KVM 6、举例安装一个windows2012R2 1、基础环境准备 【关闭防火墙】 systemctl stop firewalld systemctl disable firewalld 【关闭selinux】 修改文件/etc/selinux/config…

Linux常用指令及Web程序的部署

作者&#xff1a;~小明学编程 文章专栏&#xff1a;Linux 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 Linux中的常见指令 ls pwd cd 文件操作 touch cat mkdir echo rm cp mv man less vim head tail grep ps netstat Linux权限 搭建Ja…

模电相关知识

6 放大电路中的负反馈 6.1 反馈的基本概念及判断方法 6.4 深度负反馈放大电路放大倍数的分析 6.4.1 深度负反馈的实质 6.4.4 基于理想运放的放大倍数分析 6.4.4.1理想运放的线性工作区 理想运放的性能指标理想运放在线性区的特点 标准运放&#xff0c;有两个输入端和一个…

aws codesuit 在codebuild和codepipeline中集成jenkins

codebuild集成jenkins https://docs.aws.amazon.com/zh_cn/codebuild/latest/userguide/jenkins-plugin.html Setting up a CI/CD pipeline by integrating Jenkins with AWS CodeBuild and AWS CodeDeploy source选择本地的gitlab仓库&#xff0c;创建一个简单的springboot项…

Cert Manager 申请 SSL 证书流程及相关概念 - 一

2022.3.9 用 cert-manager 申请成功通配符证书 (*.ewhisper.cn), 2022.4.30 该证书距离过期还有 30 天&#xff0c;cert-manager 进行自动续期&#xff0c;但是却失败了。&#x1f631;&#x1f631;&#x1f631; 然后过了几天&#xff0c;在 2022.5.8, 最终成功了。如下图&a…

Vue3 项目实战 —— 后台管理系统( pc端 ) —— 动态多级导航菜单顶部侧边联动

前期回顾 0.活在风浪里的博客_CSDN博客-vue2,开源项目,Js领域博主0.活在风浪里擅长vue2,开源项目,Js,等方面的知识,0.活在风浪里关注css,safari,html5,scss,elementui,前端,es6,正则表达式,vue.js,express,ajax,webpack,echarts,json,html,typescript,sass,https,面试,ch…

离散数学-图论-图的矩阵表示(12.1)

图的矩阵表示 1 关联矩阵 定义&#xff1a;设无向图G<V,E>,V{v1,v2,⋅⋅⋅,vnv_1,v_2,,v_nv1​,v2​,⋅⋅⋅,vn​},E{e1,e2,⋅⋅⋅,eme_1,e_2,,e_me1​,e2​,⋅⋅⋅,em​},令mijm_{ij}mij​为顶点viv_ivi​与边eje_jej​的关联次数&#xff0c;则称(mij)nm(m_{ij})_{nm}…

九龙证券|景气度复苏与库存拐点双击,这个行业获主力看好!

今天计算机职业、电子、非银金融职业净流入规划居前&#xff0c;9股主力资金净流入超2亿元。 证券时报数据宝统计&#xff0c;今天沪深两市主力资金净流出46.1亿元&#xff0c;其间创业板净流出3.57亿元&#xff0c;沪深300成份股净流入28.21亿元。 申万一级职业中&#xff0c…

SpringAMQP - Work Queue 工作消息队列

目录 介绍 案例 测试 改进&#xff1a; 介绍 Work queues也被称为&#xff08;Task queues&#xff09;&#xff0c;任务模型简单来说就是让多个消费者绑定到一个队列&#xff0c;共同消费队列中的消息当消息处理比较耗时的时候&#xff0c;可能生产消息的速度会远远大于消…

机器人与未来

我们生活在“普适机器人”时代&#xff0c;机器人将像今天的智能手机一样融入日常生活&#xff0c;完成许多专门任务&#xff0c;并经常与人类并肩工作。 机器人革命将创造一个比现在更加生动和充满活力的未来。 到 2022 年&#xff0c;机器人将获得如此大的吸引力&#xff0…

全国地名点地统计模式分析

前言用不同的空间点模式分析方法&#xff0c;综合得出全国地名数据点的空间分布模式属于随机分布、均匀分布、聚集分布中的哪一种。一、点模式分析空间点模式分析是一种根据地理实体或事件的空间位置研究其分布模式的空间分析方法 。 空间点分布模式通常分为三种&#xff1a;随…

从汇编的角度去审视函数的调用【函数栈帧】

文章目录函数栈帧栈寄存器相关汇编指令函数栈帧的创建函数栈帧的销毁函数栈帧 我们在写C语言代码的时候&#xff0c;经常会把一个独立的功能抽象为函数&#xff0c;所以C程序是以函数为基本单位的。 那函数是如何调用的&#xff1f;函数的返回值又是如何待会的&#xff1f;函数…

17种编程语言实现排序算法-冒泡排序

开源地址 https://gitee.com/lblbc/simple-works/tree/master/sort 覆盖语言&#xff1a;C、C、C#、Java、Kotlin、Dart、Go、JavaScript(JS)、TypeScript(TS)、ArkTS、swift、PHP。 覆盖平台&#xff1a;安卓(Java、Kotlin)、iOS(SwiftUI)、Flutter(Dart)、Window桌面(C#)、前…

离散数学-集合论-函数(10)

函数 1 函数的概念 1.1 函数的定义 设&#x1d453;是非空集A到B的关系, 如果对每个&#x1d465;∈A, 都存在唯一的&#x1d466;∈B, 使得<&#x1d465;, &#x1d466;>∈&#x1d453;, 则称关系&#x1d453;为A到B的函数(Function), 也可称为映射(Mapping)或变…

PID优化系列之给定值斜坡函数(PLC代码+Simulink仿真测试)

很多变频器里的工艺PID,都有"PID给定值变化时间"这个参数,这里的给定值变化时间我们可以利用斜坡函数实现,当然也可以利用PT1 低通滤波器对给定值进行平滑。给定值缓慢变化在很多闭环控制系统里很重要,比如收放卷在初始建张阶段目标值不建议突变容易将卷材拉断(…