【线性表】顺序存储和链式存储的实现

文章目录

  • 顺序存储
  • 链式存储
    • 单向链表
    • 循环链表

线性表的定义

(1)概念定义:用数据元素的有限序列表示叫做线性表;线性表中数据元素的类型可以为简单类型,也可以为复杂类型。许多实际应用问题所涉的基本操作有很大相似性,不应为每个具体应用单独编写一个程序。从具体应用中抽象出共性的逻辑结构和基本操作(抽象数据类型),然后实现其存储结构和基本操作。

(2)类型定义:首先抽象出ADT List表的结构,在C/C++中一般都是采用struct来实现的。基本操作有如下:InitList(&L):创建一个新表;DestroyList(&L):销毁一个线性表;ClearList(&L):清空表;ListEmpty(L):判断表是否为空;ListLength(L):求表的长度;GetElem(L,i,&e):读取表的元素;LocateElem(L,e):查找表的元素; PriorElem(L,cur_ e,&pre _e):求表的前驱;NextElem(L,cur_ e,&next_e) :求表的后继;ListInsert(&L,i,e) :前插表;ListDelete(&L,i,&e):删除表;TraverseList (L):遍历表;

顺序存储

 顺序存储结构将线性表中的元素存储在连续的内存空间中。每个元素占据固定大小的存储空间,其物理位置和索引号相对应。顺序存储结构的优点是访问元素的速度快,缺点是插入和删除操作复杂,需要移动后续元素。
 顺序存储的底层实现就是使用数组来实现,主要就是对数组进行操作。当内存不足时重新分配一块新的内存(这块内存为原来内存的2倍),并将原来内存的值复制到新的内存里。
DynamicArray.h

#pragma once
#ifndef DYNAMIC_ARRAY_H
#define DYNAMIC_ARRAY_H

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

//动态增长内存,策略将存放数据的内存放到那?堆上
//动态数组 如果5个元素 申请内存 拷贝数据 释放内存 6插入第七个?
//容量capacity表示我的这块内存空间一共可以存放多少元素
// size概念记录当前数组中具体的元素个数了

typedef struct DYNAMICARRAY {
	int* pAddr;	//存放数据的地址
	int size;	//当前有多少个元素
	int capacity;  // 容量,我容器当前最大能容纳多少元素
}Dynamic_Array;

//写一系列的相关对DYNAMICARRAY结构体操作的函数
//初始化
Dynamic_Array* Init_Array();
//插入
void Push_Back_Array(Dynamic_Array* arr, int value);
//根据位置删除
void RemoveByPos_Array(Dynamic_Array* arr, int pos);
//根据值删除
void RemoveByValue_Array(Dynamic_Array* arr, int value);
//查找
int Find_Array(Dynamic_Array* arr, int value);
//打印
void Print_Array(Dynamic_Array* arr);
//释放动态数组的内存
void FreeSpace_Array(Dynamic_Array* arr);
// 清空数组
void Clear_Array(Dynamic_Array* arr);
//获得动态数组容量
int Capacity_Array(Dynamic_Array* arr);
//获得动态数据当前元素个数
int Size_Array(Dynamic_Array* arr);
// 根据位置获得某个位置元素
int At_Array(Dynamic_Array* arr, int pos);

#endif

DynamicArray.c

#include "DynamicArray.h"

//初始化
Dynamic_Array* Init_Array()
{
	Dynamic_Array* myarray = (Dynamic_Array*)malloc(sizeof(Dynamic_Array));
	//初始化
	myarray->capacity = 20;
	myarray->size = 0;
	myarray->pAddr = (int*)malloc(sizeof(int) * myarray->capacity);

	return myarray;
}

//插入
void Push_Back_Array(Dynamic_Array* arr, int value)
{
	if (!arr)
	{
		return;
	}

	//查看空间是否足够
	if (arr->size == arr->capacity)
	{
		//扩大容量为原来的两倍
		int* newSpace = (int*)malloc(sizeof(int) * arr->capacity * 2);
		memcpy(newSpace, arr->pAddr, arr->capacity * sizeof(int));
		//释放旧空间的内存
		free(arr->pAddr);

		arr->pAddr = newSpace;
		arr->capacity *= 2;
	}

	//插入新元素 
	arr->pAddr[arr->size] = value;
	arr->size++;
}
//根据位置删除
void RemoveByPos_Array(Dynamic_Array* arr, int pos)
{
	if (!arr)
	{
		return;
	}

	for (int i = pos; i < arr->size - 1; i++)
	{
		arr->pAddr[i] = arr->pAddr[i + 1];
	}

	arr->size--;

}
//根据值删除
void RemoveByValue_Array(Dynamic_Array* arr, int value)
{
	//找到值的位置
	int pos = Find_Array(arr, value);
	//根据位置删除
	RemoveByPos_Array(arr, pos);
}

//查找
int Find_Array(Dynamic_Array* arr, int value)
{
	if (!arr)
	{
		return -1;
	}

	int pos = -1;
	for (int i = 0; i < arr->size; i++)
	{
		if (arr->pAddr[i] == value)
		{
			pos = i;
			break;
		}
	}

	return pos;
}

//打印
void Print_Array(Dynamic_Array* arr)
{
	if (!arr)
	{
		return;
	}

	for (int i = 0; i < arr->size; i++)
	{
		printf("%d ", arr->pAddr[i]);
	}
	printf("\n");
}

//释放动态数组的内存
void FreeSpace_Array(Dynamic_Array* arr)
{
	if (!arr)
	{
		return;
	}

	if (arr->pAddr != NULL)
	{
		free(arr->pAddr);
	}

	free(arr);
}

// 清空数组
void Clear_Array(Dynamic_Array* arr)
{
	if (!arr)
	{
		return;
	}
	arr->size = 0;
}

//获得动态数组容量
int Capacity_Array(Dynamic_Array* arr)
{
	if (!arr)
	{
		return -1;
	}

	return arr->capacity;
}
//获得动态数据当前元素个数
int Size_Array(Dynamic_Array* arr)
{
	if (!arr)
	{
		return -1;
	}

	return arr->size;
}

// 根据位置获得某个位置元素
int At_Array(Dynamic_Array* arr, int pos)
{
	return arr->pAddr[pos];
}

main.c

#include "DynamicArray.h"

void test01() 
{
	//初始化动态数组
	Dynamic_Array* myArray = Init_Array();
	//打印容量
	printf("数组容量:%d\n", Capacity_Array(myArray));
	printf("数组大小:%d\n", Size_Array(myArray));
	//插入元素
	for (int i = 0; i < 30; i++) {
		Push_Back_Array(myArray, i);
	}
	printf("数组容量:%d\n", Capacity_Array(myArray));
	printf("数组大小:%d\n", Size_Array(myArray));
	//打印
	Print_Array(myArray);
	//删除
	RemoveByPos_Array(myArray, 0);
	RemoveByValue_Array(myArray, 27);
	//打印
	Print_Array(myArray);
	//查找5个位置
	int pos = Find_Array(myArray, 5);
	printf("查找第5处位置的下标(pos值):%d,值: %d\n", pos, At_Array(myArray, pos));
	//销毁
	FreeSpace_Array(myArray);
}

int main()
{
	test01();
	return 0;
}

在这里插入图片描述

链式存储

 链式存储结构将线性表中的元素存储在分散的内存空间中。每个元素由一个节点组成,包含数据和指向下一个节点的指针。链式存储结构的优点是插入和删除操作简单,无需移动其他元素。缺点是访问元素的速度较慢,需要遍历链表。

单向链表

在这里插入图片描述

 主要就是定义了一个数据结构里面包含了一个数据域和一个指针域,每一个节点的指针域指向下一个节点的地址,通过这种方式使用一个头节点就可以遍历整个链表。
LinkList.h

#pragma once
#ifndef LINKLIST_H
#define LINKLIST_H

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

//链表节点
typedef struct LINKNODE {
	void* data;		//指向任何类型的数据
	struct LINKNODE* next;
}LinkNode;

//链表结构体
typedef struct LINKLIST {
	LinkNode* head;
	int size;

}LinkList;

//打印函数指针,自定义类型写法
typedef void(*PRINTLINKNODE)(void*);

//比较函数指针
//typedef int(*COMPARENODE)(LinkNode*, LinkNode*);

//初始化链表
LinkList* Init_LinkList();
//指定位置插入
void Insert_LinkList(LinkList* list, int pos, void* data);
//删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos);
//获得链表的长度
int Size_LinkList(LinkList* list);
//查找
//int Find_LinkList(LinkList* list, void* data, COMPARENODE compare);
int Find_LinkList(LinkList* list, void* data);
//返回第一个结点
void* Front_LinkList(LinkList* list);
//打印链表结点
void Print_LinkList(LinkList* list, PRINTLINKNODE print);
//释放链表内存
void FreeSpace_LinkList(LinkList* list);

#endif // !LINKLIST_H

LinkList.c

#include "LinkList.h"

//初始化链表
LinkList* Init_LinkList()
{
	LinkList* myList = (LinkList*)malloc(sizeof(LinkList));
	myList->size = 0;

	//头结点不保存数据
	myList->head = (LinkNode*)malloc(sizeof(LinkNode));
	myList->head->data = NULL;
	myList->head->next = NULL;

	return myList;
}

//指定位置插入
void Insert_LinkList(LinkList* list, int pos, void* data)
{
	if (!list)
	{
		return;
	}

	if (pos < 0 || pos > list->size)
	{
		pos = list->size;
	}

	//创建新节点
	LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
	newNode->next = NULL;
	newNode->data = data;

	//找到辅助指针变量
	LinkNode* pCurrent = list->head;

	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}

	//新节点联入表
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;

	list->size++;
}

//删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos)
{
	if (!list)
	{
		return;
	}

	if (pos < 0 || pos >= list->size)
	{
		return;
	}

	LinkNode* pCurrent = list->head;
	for (int i = 0; i < pos; i++) 
	{
		pCurrent = pCurrent->next;
	}

	LinkNode* pDel = pCurrent->next;
	pCurrent->next = pDel->next;

	free(pDel);

	list->size--;
}

//获得链表的长度
int Size_LinkList(LinkList* list)
{
	return list->size;
}
//查找
int Find_LinkList(LinkList* list, void* data)
{
	if (!list || !data)
	{
		return -1;
	}

	LinkNode* pCurrent = list->head->next;

	int index = 0;
	int flag = -1;

	while (pCurrent)
	{
		if (pCurrent->data == data)
		{
			flag = index;
			break;
		}
		index++;
		pCurrent = pCurrent->next;
	}
	return flag;
}
//返回第一个结点
void* Front_LinkList(LinkList* list)
{
	return list->head->next->data;
}
//打印链表结点
void Print_LinkList(LinkList* list, PRINTLINKNODE print)
{
	if (!list)
	{
		return;
	}

	LinkNode* pCurrent = list->head->next;

	while (pCurrent)
	{
		print(pCurrent->data);
		pCurrent = pCurrent->next;
	}
}

//释放链表内存
void FreeSpace_LinkList(LinkList* list)
{
	if (!list)
	{
		return;
	}

	LinkNode* pCurrent = list->head->next;

	while (pCurrent)
	{
		LinkNode* pNode = pCurrent->next;
		free(pCurrent);
		pCurrent = pNode;
	}

	list->size = 0;
	free(list);
}

main.c

#include "LinkList.h"


//自定义数据类型
typedef struct PERSON {
	char name[64];
	int age;
	int score;
}Person;

void MyPrint(void* data)
{
	Person* person = (Person*)data;
	printf("结点数据:Name:%s, Age:%d, Score:%d\n", person->name, person->age, person->score);
}

int main()
{
	//创建一个链表
	LinkList* list = Init_LinkList();
	//创建数据
	Person p1 = { "青铜", 18, 80 };
	Person p2 = { "白银", 19, 85 };
	Person p3 = { "黄金", 20, 90 };
	Person p4 = { "钻石", 21, 95 };
	Person p5 = { "星耀", 22, 100 };

	//数据插入链表
	Insert_LinkList(list, 0, &p1);
	Insert_LinkList(list, 0, &p2);
	Insert_LinkList(list, 0, &p3);
	Insert_LinkList(list, 0, &p4);
	Insert_LinkList(list, 0, &p5);

	//打印
	Print_LinkList(list, MyPrint);

	//删除3
	RemoveByPos_LinkList(list, 3);

	//打印
	printf("--------------------\n");
	Print_LinkList(list, MyPrint);

	//返回第一个结点
	printf("--------------------\n");
	Person* ret = (Person*)Front_LinkList(list);
	printf("首结点数据:Name:%s, Age:%d, Score:%d\n", ret->name, ret->age, ret->score);

	/*
	//查找(比较的是已有指针类型的data),返回其索引值
	Person f1 = { "青铜2", 18, 80 };
	Person f2 = { "青铜", 18, 80 };
	int index = Find_LinkList(list, &f1, MyCompare);
	printf("查到的索引值:%d", index);
	*/
	//销毁链表
	FreeSpace_LinkList(list);

	return 0;
}

在这里插入图片描述

循环链表

在这里插入图片描述
 循环链表和单链表的主要区别就是循环链表的尾节点的指针域会指向头结点的节点。
CircleLinkList.h

#pragma once
#ifndef CIRCLELINKLIST_H
#define CIRCLELINKLIST_H

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

//链表的小节点
typedef struct CIRCLELINKNODE {
	struct CIRCLELINKNODE* next;
}CircleLinkNode;

//链表结构体
typedef struct CIRCLELINKLIST {
	CircleLinkNode head;
	int size;
}CircleLinkList;

//编写针对链表结构体操作的API函数

#define CIRCLELINKLIST_TRUE 1
#define CIRCLELINKLIST_FALSE 0

//比较回调
typedef int(*COMPARENODE)(CircleLinkNode*, CircleLinkNode*);

//打印回调
typedef void(*PRINTNODE)(CircleLinkNode*);

//初始化函数
CircleLinkList* Init_CircleLinkList();
//插入函数
void Insert_CircleLinkList(CircleLinkList* clist, int pos, CircleLinkNode* data);
// 获得第一个元素
CircleLinkNode* Front_CircleLinkList(CircleLinkList* clist);
//根据位置删除
void RemoveByPos_CircleLinkList(CircleLinkList* clist, int pos);
//根据值去删除
void RemoveByValue_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare);
//获得链表的长度
int Size_CircleLinkList(CircleLinkList* clist);
//判断是否为空
int IsEmpty_CircleLinkList(CircleLinkList* clist);
//查找
int Find_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare);
//打印节点
void Print_CircleLinkList(CircleLinkList* clist, PRINTNODE print);
//释放内存
void FreeSpace_CircleLinkList(CircleLinkList* clist);

#endif // !CIRCLELINKLIST_H

CircleLinkList.c

#include "CircleLinkList.h"

//初始化函数
CircleLinkList* Init_CircleLinkList()
{
	CircleLinkList* list = (CircleLinkList*)malloc(sizeof(CircleLinkList));

	list->head.next = &(list->head);
	list->size = 0;

	return list;
}
//插入函数
void Insert_CircleLinkList(CircleLinkList* clist, int pos, CircleLinkNode* data)
{
	if (!clist)
	{
		return;
	}

	if (pos<0 || pos>clist->size)
	{
		pos = clist->size;
	}

	CircleLinkNode* pCurrent = &(clist->head);

	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}

	data->next = pCurrent->next;
	pCurrent->next = data;

	clist->size++;
}
// 获得第一个元素
CircleLinkNode* Front_CircleLinkList(CircleLinkList* clist)
{
	return clist->head.next;
}

//根据位置删除
void RemoveByPos_CircleLinkList(CircleLinkList* clist, int pos)
{
	if (!clist)
	{
		return;
	}

	if (pos < 0 || pos >= clist->size)
	{
		return;
	}

	CircleLinkNode* pCurrent = &(clist->head);
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}

	pCurrent->next = pCurrent->next->next;

	clist->size--;
}

//根据值去删除
void RemoveByValue_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare)
{
	if (!clist || !data)
	{
		return;
	}

	CircleLinkNode* pPrev = &(clist->head);
	CircleLinkNode* pCurrent = pPrev->next;
	for (int i = 0; i < clist->size; i++)
	{
		if (compare(pCurrent, data) == CIRCLELINKLIST_TRUE)
		{
			pPrev->next = pCurrent->next;
			clist->size--;
			break;
		}

		pPrev = pCurrent;
		pCurrent = pCurrent->next;
	}
}

//获得链表的长度
int Size_CircleLinkList(CircleLinkList* clist)
{
	return clist->size;
}

//判断是否为空
int IsEmpty_CircleLinkList(CircleLinkList* clist)
{
	if (clist->size == 0) 
	{
		return CIRCLELINKLIST_TRUE;
	}
	return CIRCLELINKLIST_FALSE;
}

//查找
int Find_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare)
{
	if (!clist || !data)
	{
		return -1;
	}

	int index = 0;
	int flag = -1;

	CircleLinkNode* pCurrent = clist->head.next;

	for (int i = 0; i < clist->size; i++)
	{
		if (compare(pCurrent, data) == CIRCLELINKLIST_TRUE)
		{
			flag = index;
			break;
		}

		pCurrent = pCurrent->next;
		index++;
	}

	return index;
}

//打印节点
void Print_CircleLinkList(CircleLinkList* clist, PRINTNODE print)
{
	if (!clist)
	{
		return;
	}

	CircleLinkNode* pCurrent = clist->head.next;

	for (int i = 0; i < clist->size * 2; i++)
	{
		if (pCurrent == &(clist->head))
		{
			pCurrent = pCurrent->next;
			printf("-----------------------\n");
		}

		print(pCurrent);
		pCurrent = pCurrent->next;
	}
}

//释放内存
void FreeSpace_CircleLinkList(CircleLinkList* clist)
{
	if (!clist)
	{
		return;
	}

	free(clist);
}

main.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CircleLinkList.h"

typedef struct PERSON {
	CircleLinkNode node;
	char name[64];
	int age;
	int score;
} Person;

void MyPrint(CircleLinkNode* data) {
	Person* p = (Person*)data;
	printf("Name:%s, Age:%d, Score:%d\n", p->name, p->age, p->score);
}

int MyCompare(CircleLinkNode* data1, CircleLinkNode* data2) {
	Person* p1 = (Person*)data1;
	Person* p2 = (Person*)data2;

	if (strcmp(p1->name, p2->name) == 0 && p1->age == p2->age && p1->score == p2->score) {
		return CIRCLELINKLIST_TRUE;
	}
	return CIRCLELINKLIST_FALSE;
}
int main(void) {

	//创建循环链表
	CircleLinkList* clist = Init_CircleLinkList();
	//创建数据
	Person p1, p2, p3, p4, p5;
	strcpy(p1.name, "aaa");
	strcpy(p2.name, "bbb");
	strcpy(p3.name, "ccc");
	strcpy(p4.name, "ddd");
	strcpy(p5.name, "eee");

	p1.age = 10;
	p2.age = 20;
	p3.age = 30;
	p4.age = 40;
	p5.age = 50;

	p1.score = 50;
	p2.score = 60;
	p3.score = 70;
	p4.score = 80;
	p5.score = 90;

	//数据入链表
	Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p1);
	Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p2);
	Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p3);
	Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p4);
	Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p5);

	//打印
	Print_CircleLinkList(clist, MyPrint);

	Person pDel;
	strcpy(pDel.name, "ccc");
	pDel.age = 30;
	pDel.score = 70;

	//根据值删除
	RemoveByValue_CircleLinkList(clist, (CircleLinkNode*)&pDel, MyCompare);

	//打印
	printf("------------\n");
	Print_CircleLinkList(clist, MyPrint);
	//释放内存
	FreeSpace_CircleLinkList(clist);

	system("pause");
	return 0;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day02 设计首页导航条

设计首页导航条 导航条的样式&#xff0c;主要是从Material DesignThemes UI 拷贝过来修改的,项目用了这个UI组件库。就看项目需要什么&#xff0c;就去源码拷过来使用。 直接下载源码&#xff0c;编译运行就可以看到Demo 了 下载后且正常编译成功了&#xff0c;是能正常跑起来…

如何使用Python绘制出好看的小提琴图、箱形图、散点图、山脊图和柱状图

如何使用Python绘制出好看的小提琴图、箱形图、散点图、山脊图和柱状图 废话不多说&#xff0c;今天给大家分享一个&#xff0c;使用python绘制小提琴图、箱形图、散点图、山脊图和柱状图等等 图中的数据是随机生成的&#xff0c;图例&#xff0c;图注以及坐标题目各种信息&a…

javascript之对象属性配置

属性标志&#xff1a; 介绍&#xff1a; 对象属性&#xff0c;除 value 外&#xff0c;还有三个特殊的特性&#xff0c;也就是所谓的“标志”&#xff1a; 属性truefalsewritable值可以被修改只可读的enumerable被在循环中列出不会被列出configurable此属性可以被删除/修改 不可…

从头开始构建GPT标记器

从头开始构建GPT标记器 对于GPT Tokenizer&#xff0c;论文《Language Models are Unsupervised Multitask Learners》中介绍了一种字节级编码作为LLM的标记化机制&#xff1a; The vocabulary is expanded to 50,257. We also increase the context size from 512 to 1024 to…

python3.8环境下安装pyqt5

1.实验目的 测试python可视化工具包pyqt5,为后期做系统前端页面做铺垫 2.实验环境 1.软件 anaconda2.5 pycharm2024.1.1 pyqt5 2.硬件 GPU 4070TI Intel I7 1400K 3. 安装步骤 (base) C:\Users\PC>conda -V conda 23.7.4(base) C:\Users\PC>conda create qttest p…

基于卷积-小波神经网络的SAR图像海冰变化检测方法(MATLAB R2018A)

海冰是冰冻圈的重要组成部分&#xff0c;海冰的变化信息对航行安全和自然资源开采等非常重要&#xff0c;许多船舶没有加固防冰设备&#xff0c;因此&#xff0c;必须避开所有的冰区。尤其当冰压很高时&#xff0c;即使破冰船也很难在冰层中前行。为了安全航行&#xff0c;获取…

ctfshow-web入门-爆破(web21-web24)

目录 1、web21 2、web22 3、web23 4、web24 1、web21 爆破什么的&#xff0c;都是基操 需要认证才能访问 随便输一个用户名和密码抓包看看&#xff1a; 多出来一个认证的头 Authorization: Basic YWRtaW46MTIzNDU2 base64 解码看看&#xff1a; 就是我们刚才输入的用于测…

JVM之【运行时数据区2——堆】

三、堆&#xff08;Heap&#xff09; 1、什么是堆 在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;堆&#xff08;Heap&#xff09;是用于动态分配内存的区域。在Java程序运行时&#xff0c;所有对象和数组都是在堆中分配内存的。堆是Java内存模型的重要组成部分&…

云计算-云基础设施的配置 (Provisioning Cloud Infrastructure)

AWS CloudFormation (AWS CloudFormation) 它是一项服务&#xff0c;允许我们自动建模和配置所需的AWS资源。可以使用模板来实现这一目的。这个模板基本上是用JSON或YAML格式编写的。AWS CloudFormation会根据模板描述的内容来实施资源的配置和管理。我们可以成组配置和管理一组…

MySQL—函数—日期函数(基础)

一、引言 接下来讨论和学习关于函数的第三个方面——日期函数。 常见的MySQL当中的日期函数。 注意&#xff1a; 1、CURDATE()&#xff1a;cur&#xff1a;current 当前的&#xff0c;返回的是当前日期。 2、CURTIME()&#xff1a;当前时间。 3、NOW&#xff1a;当前的日期和…

一、实现一个简单的 Google Chrome 扩展程序

目录 &#x1f9ed; 效果展示 # 图示效果 a. 拓展程序列表图示效果&#xff1a; b. 当前选项卡页面右键效果&#xff1a; c. 拓展程序消息提示效果&#xff1a; &#x1f4c7; 项目目录结构 # 说明 # 结构 # 文件一览 ✍ 核心代码 # manifest.json # background.j…

Unity中帧动画素材的切割设置

有几个问题&#xff0c;美术在给我们帧动画的时候&#xff0c;一般都是给一个比较大的图&#xff0c;然后进行切割成多个sprite&#xff0c;导入到animation中 一般来说&#xff0c;进行那个autoSlide&#xff0c;自动切割就可以了 这个自动切割的图片会沿着有像素的最小包围…

内网-2(代理)

一、代理概述 1、代理服务器(proxy server)&#xff1a;代理网络用户去取得网络信息&#xff0c;介于浏览器与web服务器之间的一条服务器。 注&#xff1a;为了方便&#xff0c;以下用B来代表浏览器的主机&#xff0c;S来代表服务器的主机。 2、正向代理和反向代理 正向代…

车载诊断内容汇总(培训+视频)

车载诊断内容汇总 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c…

虚拟现实环境下的远程教育和智能评估系统(二)

本周进行开发工具&#xff0c;技术框架选择与学习&#xff1b;基本了解了以下技术框架的部署应用&#xff1b; 一、Springboot&#xff1a;最常用的后端框架之一&#xff0c;通过提供默认配置和自动配置&#xff0c;消除许多手动配置和样板代码&#xff0c;从而加速基于Spring…

CentOS7单用户模式,救援模式操作记录

CentOS7单用户模式&#xff0c;救援模式操作记录 1. 单用户模式 单用户模式进入不需要密码&#xff0c;无网络连接&#xff0c;拥有root权限&#xff0c;禁止远程登陆。一般用于用于系统维护&#xff0c;例如忘记root密码后可以通过进入单用户模式进行重置。 开机启动&#…

JVM运行时数据区 - 程序计数器

运行时数据区 Java虚拟机在执行Java程序的过程中&#xff0c;会把它管理的内存划分成若干个不同的区域&#xff0c;这些区域有各自的用途、创建及销毁时间&#xff0c;有些区域随着虚拟机的启动一直存在&#xff0c;有些区域则随着用户线程的启动和结束而建立和销毁&#xff0…

Unity DOTS技术(二)ECS

文章目录 一.ECS简介二.基本操作实例三.实体查看组件四.位置实体修改五.旋转实体六.了解原有属性七.禁止自动创建八.动态实例化 一.ECS简介 ECS全称 (Entity Component System).即(E:实体 C:组件 S:系统). 实际上即是数据方法分离.数据放在组件里,具体实现放在系统里.组件挂载…

遥感影像信息提取

刘老师&#xff08;副教授&#xff09;&#xff0c;来自双一流重点高校&#xff0c;长期从事GIS/RS/3S技术及其生态环境领域中的应用等方面的研究和教学工作&#xff0c;并参与GIS的二次开发&#xff0c;发表多篇sci论文&#xff0c;具有资深的技术底蕴和专业背景。 专题一&am…

Java反序列化漏洞与URLDNS利用链分析

前言 前面学习过 Java 反序列化漏洞的部分知识&#xff0c;总结过几篇文章&#xff1a; 文章发布日期内容概括《渗透测试-JBoss 5.x/6.x反序列化漏洞》2020-07-08JBoss 反序列化漏洞 CVE-2017-12149 的简单复现&#xff0c;使用了 ysoserial 和 CC5 链&#xff0c;未分析漏洞…