【数据结构初阶】顺序表

news2024/11/17 1:28:12

各位读者老爷好,又见面了哈!鼠鼠我呀现在基于C语言浅浅介绍一下数据结构初阶中的顺序表,希望对你有所帮助!

目录

1.线性表 

2.顺序表

2.1概念即结构

2.2动态顺序表接口的实现

2.2.1定义顺序表

2.2.2初始化

2.2.3销毁 

2.2.4打印

2.2.5尾插

2.2.6头插 

2.2.7头删

2.2.8尾删 

2.2.9顺序表查找

 2.2.10顺序表在下标pos位置插入数据x

2.2.11 顺序表删除下标pos位置的值

3.顺序表使用 

3.1test.c

3.2SeqList.h

3.SeqList.c

4.小知识累积(与顺序表无关)

4.1数组越界一定会报错吗?

4.2数组的下标为什么不从1开始而要从0开始呢? 

5.ending

额额额,好哈!顺序表是线性表的一种哈!那我们看看下面是线性表!

1.线性表 

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

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

咱们下面介绍的顺序表是一种在逻辑上和物理结构上是连续的。

2.顺序表

2.1概念即结构

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

与数组不同的是,数组可以在不越界的情况下任意位置存储数据,而顺序表要求数据只能从头开始连续存储。

 顺序表一般可以分为:

1.静态顺序表:使用定长数组存储数据

//顺序表的静态存储
#define N 7
#typedef int SLDataType
typedef struct SeqList
{
SLDataType array[N];//定长数组
size_t size;//有效数据的个数
}SeqList;

2.动态顺序表:使用动态开辟的数组存储

//顺序表的动态存储
#typedef int SLDataType
typedef struct SeqList
{
SLDataType*array;//指向动态开辟的数组
size_t size;//有效数据的个数
size_t capicity;//容量空间的大小
}SeqList;

2.2动态顺序表接口的实现

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

2.2.1定义顺序表
typedef int SLDateType;

typedef struct SeqList
{
	SLDateType* a;
	int size;                                           //有效数据
	int capaticy;                                       //空间容量
}SeqList;

根据上面定义的顺序表,咱们创建一个顺序表s1,并实现该顺序表一系列接口实现。

SeqList s1;//顺序表
2.2.2初始化
void SeqListInit(SeqList* ps)                               //初始化
{
	assert(ps);
	ps->a = NULL;
	ps->capaticy = 0;
	ps->size = 0;
}

咱们使用顺序表之前需要将有效数据size和空间容量capaticy置零,同时不妨将指向动态开辟数组的指针a置为NULL。

ps:这个函数的参数接收的是上面创建的顺序表s1的地址。

question:实现这个初始化函数参数为啥是s1的地址而不是s1呢?

answer:因为形参是实参的一份临时拷贝,形参的改变不会影响实参。就以这个初始化函数为例,如果这个函数参数是"SeqList s2"的话 ,虽然这个函数中将s2的成员a置为NULL、将s2的成员size和capaticy都置为零,但根本影响不了顺序表s1的成员a、size和capaticy。

就是因为这个原因,下面接口的实现都是采用传递s1的地址。

2.2.3销毁 
void SeqListDestroy(SeqList*ps)                              //销毁
{
	assert(ps);
	if (ps->a != NULL)
	{
		ps->a = NULL;
		ps->capaticy = 0;
		ps->size = 0;
	}
}

咱们如果不再使用顺序表的话,因为顺序表的成员a指向动态开辟的数组,所以最好将这块空间free掉,size和capaticy也最好置零。

 ps:这个函数的参数接收的是上面创建的顺序表s1的地址。

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

必要时可以将存储在顺序表的数据打印出来看看,因为有size个数据,所以循环打印size次即可将数据全部打印出来。

 ps:这个函数的参数接收的是上面创建的顺序表s1的地址。

2.2.5尾插
void SLCheckcapacity(SeqList* ps)                        //扩容
{
	assert(ps);
	if (ps->size == ps->capaticy)
	{
		int newcapaticy = (ps->capaticy == 0) ? 4 : 2 * (ps->capaticy);
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * newcapaticy);
		if (tmp == NULL)
		{
			perror("calloc fail");
			return;
		}
		ps->a = tmp;
		ps->capaticy = newcapaticy;
	}
}
void SeqListPushBack(SeqList* ps, SLDateType x)               //尾插
{
	assert(ps);
	SLCheckcapacity(ps);
	ps->a[ps->size] = x;
	ps->size += 1;
}

在顺序表的末尾(下标为size处)处插入数据时直接插入,size加一即可。但要考虑顺序表容量空间是否足够,所以要调用扩容函数SLCheckcapacity,扩容函数的实现大致时当顺序表的size和capaticy一样时,调用realloc函数二倍扩容。 

ps:尾插函数的参数接收的是上面创建的顺序表s1的地址。

2.2.6头插 
void SLCheckcapacity(SeqList* ps)                        //扩容
{
	assert(ps);
	if (ps->size == ps->capaticy)
	{
		int newcapaticy = (ps->capaticy == 0) ? 4 : 2 * (ps->capaticy);
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * newcapaticy);
		if (tmp == NULL)
		{
			perror("calloc fail");
			return;
		}
		ps->a = tmp;
		ps->capaticy = newcapaticy;
	}
}
void SeqListPushFront(SeqList* ps, SLDateType x)              //头插
{
	assert(ps);
	SLCheckcapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
}

顺序表头部插入数据就是将第二个及以后的数据均后移,在将所需头插数据x插入到顺序表头部,size加一即可,同样要考虑容量问题。

 ps:头插函数的第一个参数接收的是上面创建的顺序表s1的地址,第二个参数是所需头插数据。

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

顺序表删除头部数据也很简单,将第二个及以后的数据均向前覆盖,在将size减一即可。但是需要注意的是,如果size为零的话说明没有数据就不要再删了,用assert断言一下就行。

  ps:这个函数的参数接收的是上面创建的顺序表s1的地址。

2.2.8尾删 
void SeqListPopBack(SeqList* ps)                              //尾删
{
	assert(ps);
	assert(ps->size >0);
	ps->size--;
}

顺序表尾部删除数据最简单,直接将size减一就行,但和头删一样,用assert断言一下防止删空了。

  ps:这个函数的参数接收的是上面创建的顺序表s1的地址。

2.2.9顺序表查找
int SeqListFind(SeqList* ps, SLDateType x)                     //顺序表查找
{
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (x == ps->a[i])
		{
			return i;//找得到返回下标
		}
	}
	return -1;//找不到返回-1
}

我们也许需要在顺序表中查找某个数据,所以遍历这个顺序表的数据即可,找到返回该数据下标,找不到返回-1。

 ps:该函数的第一个参数接收的是上面创建的顺序表s1的地址,第二个参数是所需查找的数据。

 2.2.10顺序表在下标pos位置插入数据x
void SLCheckcapacity(SeqList* ps)                        //扩容
{
	assert(ps);
	if (ps->size == ps->capaticy)
	{
		int newcapaticy = (ps->capaticy == 0) ? 4 : 2 * (ps->capaticy);
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * newcapaticy);
		if (tmp == NULL)
		{
			perror("calloc fail");
			return;
		}
		ps->a = tmp;
		ps->capaticy = newcapaticy;
	}
}
void SeqListInsert(SeqList* ps, int pos, SLDateType x)           //顺序表在下标pos位置插入x
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLCheckcapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;
}

这个接口的实现大致是将下标pos以后的数据都往后挪,在将所需插入的数据x插入到下标pos的位置,在将size加一即可。但有几处细节要注意:1.pos只能在0和size之间(包括0和size), 否则就越界访问了,所以利用assert断言一下;2.防止顺序表容量不足,调用扩容函数。

ps:该函数的第一个参数接收的是上面创建的顺序表s1的地址,第二个参数是插入位置的下标,第三个参数是需插入的数据。

2.2.11 顺序表删除下标pos位置的值
void SeqListErase(SeqList* ps, int pos)    // 顺序表删除下标pos位置的值
{
	assert(ps);
	assert(pos >= 0 && pos< ps->size);
	int begin = pos + 1;
	while (begin <= ps->size - 1)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}

这个接口实现大致就是将下标pos以后的数据均向前覆盖,size减一即可,若需删除最后一个(下标为size-1)数据 ,无需覆盖,直接size减一即可。细节:下标pos只能在0到size之间(包括0),否则会越界访问,利用assert断言。

ps:该函数第一个参数接收的是上面创建的顺序表s1的地址,第二个参数是需删除数据的下标。

3.顺序表使用 

咱们顺序表接口就实现完了。可以写一个接口来对接上面的所以接口,以实现顺序表的增删查改及初始化、销毁、打印等功能。鼠鼠我写了一个,可以参考参考哈:

3.1test.c

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void menu()
{
	printf("**********************\n");
	printf("********0.退出********\n");
	printf("****1.头插  2.头删****\n");
	printf("****3.尾插  4.尾删****\n");
	printf("****5.查找  6.打印****\n");
	printf("*7.在下标pos位置插入值\n");
	printf("*8.删除下标pos位置的值\n");
	printf("**********************\n");
}
int main()
{
	SeqList s1;
	SeqListInit(&s1);
	int input;
	do 
	{
		menu();
		printf("请输入你想操作的数字:->");
		scanf("%d", &input);
		if (input == 0)
		{
			SeqListDestroy(&s1);
			printf("\n");
			break;
		}
		else if (input == 1)
		{
			SLDateType x = 0;
			printf("请输入你要插入的值:->");
			scanf("%d", &x);
			SeqListPushFront(&s1, x);
			printf("\n");
		}
		else if (input == 2)
		{
			SeqListPopFront(&s1);
			printf("\n");
		}
		else if (input == 3)
		{
			SLDateType x = 0;
			printf("请输入你要插入的值:->");
			scanf("%d", &x);
			SeqListPushBack(&s1, x);
			printf("\n");
		}
		else if (input == 4)
		{
			SeqListPopBack(&s1);
			printf("\n");
		}
		else if (input == 5)
		{
			SLDateType x = 0;
			printf("请输入你要查找的值:->");
			scanf("%d", &x);
			int flag=SeqListFind(&s1, x);
			if (flag!=-1)
			{
				printf("你要查找的值下标是%d\n", flag);
			}
			else
			{
				printf("找不到!\n");
			}
			printf("\n");
		}
		else if (input == 6)
		{
			SeqListPrint(&s1);
			printf("\n");
		}
		else if (input == 7)
		{
			SLDateType x = 0; int pos = 0;
			printf("请分别输入你要插入的值及插入的下标:->");
			scanf("%d %d", &x, &pos);
			SeqListInsert(&s1,pos,x);
			printf("\n");
		}
		else if (input == 8)
		{
			int pos = 0;
			printf("请输入你要删除值的下标:->");
			scanf("%d", &pos);
			SeqListErase(&s1,pos);
			printf("\n");
		}
		else
		{
			printf("输入错误,请重新输入:->");
		}
	} while (input);
	return 0;
}

3.2SeqList.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLDateType;

typedef struct SeqList
{
	SLDateType* a;
	int size;                                           //有效数据
	int capaticy;                                       //空间容量
}SeqList;

void SeqListInit(SeqList* ps);                          //初始化

void SeqListDestroy(SeqList* ps);                       //销毁

void SeqListPrint(SeqList* ps);                         //打印

void SeqListPushBack(SeqList* ps, SLDateType x);        //尾插

void SeqListPushFront(SeqList* ps, SLDateType x);       //头插

void SeqListPopFront(SeqList* ps);                      //头删

void SeqListPopBack(SeqList* ps);                       //尾删

int SeqListFind(SeqList* ps, SLDateType x);             //顺序表查找

void SeqListInsert(SeqList* ps, int pos, SLDateType x); // 顺序表在下标pos位置插入x

void SeqListErase(SeqList* ps, int pos);                // 顺序表删除下标pos位置的值

3.SeqList.c

#define _CRT_SECURE_NO_WARNINGS 
#include"SeqList.h"


void SLCheckcapacity(SeqList* ps)                        //扩容
{
	assert(ps);
	if (ps->size == ps->capaticy)
	{
		int newcapaticy = (ps->capaticy == 0) ? 4 : 2 * (ps->capaticy);
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * newcapaticy);
		if (tmp == NULL)
		{
			perror("calloc fail");
			return;
		}
		ps->a = tmp;
		ps->capaticy = newcapaticy;
	}
}


void SeqListInit(SeqList* ps)                               //初始化
{
	assert(ps);
	ps->a = NULL;
	ps->capaticy = 0;
	ps->size = 0;
}


void SeqListDestroy(SeqList*ps)                              //销毁
{
	assert(ps);
	if (ps->a != NULL)
	{
		ps->a = NULL;
		ps->capaticy = 0;
		ps->size = 0;
	}
}


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


void SeqListPushBack(SeqList* ps, SLDateType x)               //尾插
{
	assert(ps);
	SLCheckcapacity(ps);
	ps->a[ps->size] = x;
	ps->size += 1;
}


void SeqListPushFront(SeqList* ps, SLDateType x)              //头插
{
	assert(ps);
	SLCheckcapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
}


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


void SeqListPopBack(SeqList* ps)                              //尾删
{
	assert(ps);
	assert(ps->size >0);
	ps->size--;
}


int SeqListFind(SeqList* ps, SLDateType x)                     //顺序表查找
{
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (x == ps->a[i])
		{
			return i;//找得到返回下标
		}
	}
	return -1;//找不到返回-1
}


void SeqListInsert(SeqList* ps, int pos, SLDateType x)           //顺序表在下标pos位置插入x
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLCheckcapacity(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(SeqList* ps, int pos)                          // 顺序表删除下标pos位置的值
{
	assert(ps);
	assert(pos >= 0 && pos< ps->size);
	int begin = pos + 1;
	while (begin <= ps->size - 1)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}

 各位读者老爷可以将这三个文件放到一个工程下玩玩哦!

4.小知识累积(与顺序表无关)

4.1数组越界一定会报错吗?

answer:越界读基本不会报错。越界写可能会报错。越界的检查是一种抽查行为,就像查酒驾一样,比如数组通常会在数组后面设置一些标记位,一旦标记位的 值被更改就会报错,所以一般在数组末尾附近越界写会报错,但越界太远写就基本不报错了(跳过了标记位)。当然不同的编译器对越界的检查不同。这里只是对越界报错的一种认知。

4.2数组的下标为什么不从1开始而要从0开始呢? 

因为通过下标访问数组本质是指针访问,数组下标从0开始是要和指针的设计自恰!

a[i]等价于*(a+i),只有当下标从0开始时,当i=0时,a[0]=*(a+0)才解释得通。

5.ending

鼠鼠我才疏学浅,且时间紧迫,如有不足,恳请斧正,谢谢哈哈哈!

懂我意思吧?

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

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

相关文章

kubenetes-容器运行时接口CRI

一、CRI 容器运行时&#xff08;Container Runtime&#xff09;&#xff0c;运行于Kubernetes&#xff08;K8s&#xff09; 集群的每个节点中&#xff0c;负责容器的整个生命周期。其中Docker是目前应用最广的。随着容器云的发展&#xff0c;越来越多的容器运行时涌现。 为了解…

UE特效案例 —— 角色刀光

目录 一&#xff0c;环境配置 二&#xff0c;场景及相机设置 三&#xff0c;效果制作 刀光制作 地裂制作 击打地面炸开制作 一&#xff0c;环境配置 创建默认地形Landscape&#xff0c;如给地形上材质需确定比例&#xff1b;添加环境主光源DirectionalLight&#xff0c;设…

电路综合-基于简化实频的SRFT集总参数切比雪夫低通滤波器设计

电路综合-基于简化实频的SRFT集总参数切比雪夫低通滤波器设计 6、电路综合-基于简化实频的SRFT微带线切比雪夫低通滤波器设计中介绍了使用微带线进行切比雪夫滤波器的设计方法&#xff0c;在此对集总参数的切比雪夫响应进行分析。 SRFT集总参数切比雪夫低通滤波器综合不再需要…

C语言——打印1000年到2000年之间的闰年

闰年&#xff1a; 1、能被4整除不能被100整除 2、能被400整除 #define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int year;for(year 1000; year < 2000; year){if((year%4 0) && (year%100!0) || (year%400 0)){printf("%d ",ye…

算法之双指针

双指针算法的作用 双指针算法是一种使用2个变量对线性结构(逻辑线性/物理线性)&#xff0c;进行操作的算法&#xff0c;双指针可以对线性结构进行时间复杂度优化&#xff0c;可以对空间进行记忆或达到某种目的。 双指针算法的分类 1.快慢指针 2.滑动窗口 3.左右指针 4.前后指…

Keil文本对齐

摘要&#xff1a;通常我们写代码的时候&#xff0c;尤其是缩进和{}的使用&#xff0c;很多都需要自己手动去调整&#xff0c;如果有一个自动格式化代码的工具&#xff0c;每次编辑完代码&#xff0c;然后一键给将代码格式化&#xff0c;即省时又美观。为了解决这个问题&#xf…

红黑树,AVLTree树(平衡二叉树)迭代器原理讲解

红黑树&#xff0c;AVLTree树底层实现逻辑都是平衡二叉树&#xff08;AVLTree高度平衡&#xff0c;红黑树以某种规则平衡&#xff09;&#xff0c;但终究不像链表的迭代器那样逻辑简单。 简单叙述以下&#xff0c;二叉树上面迭代器的运行逻辑&#xff0c;根据下面的图&#xff…

洛谷 P3842 [TJOI2007] 线段 python解析

P3842 [TJOI2007] 线段 时间&#xff1a;2023.11.7 题目地址&#xff1a;[TJOI2007] 线段 题目分析 这题就是练一下动态规划的。 首先确定dp数组: d p [ i ] [ 0 / 1 ] dp[i][0/1] dp[i][0/1]&#xff0c; i i i代表第几行&#xff0c;然后每行 d p [ i ] [ 0 ] dp[i][0] d…

Leetcode—20.有效的括号【简单】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—20.有效的括号 C实现代码 class Solution { public:bool isValid(string s) {stack<char> arr;int len s.size();if(len 1) {return false;}for(int i 0; i < len; i) {if(s[i] ( || s[i] [ || s[i] {)…

Lambertian模型(完美漫反射)

这里使用相乘的方式组合光照色和纹理色。根据这个模型,面朝光源的区域光照强度高,纹理色也相应增强。面背光源的区域光照弱,纹理色也被抑制。这样通过光照和纹理的结合,可以合成出具有照明效果的面部颜色,而不仅仅是固定的纹理本身的颜色。相乘方式可以近似实现不同光照方向下面…

浙大恩特客户资源管理系统 fileupload.jsp 任意文件上传

一、漏洞描述 杭州恩软信息技术有限公司&#xff08;浙大恩特&#xff09;提供外贸管理软件、外贸客户管理软件等外贸软件&#xff0c;是一家专注于外贸客户资源管理及订单管理产品及服务的综合性公司。 浙大恩特客户资源管理系统中的fileupload.jsp接口存在安全漏洞&#xf…

DevChat智能编程助手:小白也能轻松上手的开发利器

DevChat智能编程助手&#xff1a;小白也能轻松上手的开发利器 一、DevChat介绍1.1 DevChat简介1.2 DevChat特点1.3 DevChat官网 二、注册DevChat账号2.1 访问DevChat官网2.2 注册账号2.3 复制Access Key2.4 登录DevChat 三、安装DevChat3.1 打开VS Code软件3.2 安装DevChat3.3 …

Cocos开发

harmonyOS开发 在Cocos Creator中&#xff0c;场景是一个独立的文件资源&#xff0c;可以像打开PSD文件一样在编辑器中双击打开&#xff1b; 场景文件是数据驱动工作流的核心&#xff0c;场景中包括图像资源、动画、特效以及驱动游戏逻辑和表现的脚本&#xff1b; Cocos Crea…

PCA(主成分分析)数据降维技术代码详解

引言 随着大数据时代的到来&#xff0c;我们经常会面临处理高维数据的问题。高维数据不仅增加了计算复杂度&#xff0c;还可能引发“维度灾难”。为了解决这一问题&#xff0c;我们需要对数据进行降维处理&#xff0c;即在不损失太多信息的前提下&#xff0c;将数据从高维空间…

网络通讯基础

Socket Socket是应用层与TCP/IP协议簇通信的中间软件抽象层&#xff0c;它是一组接口。Socket通常用于实现客户端和服务器之间的通信。它允许客户端应用程序与服务器应用程序建立连接&#xff0c;并通过网络传输数据。 Socket包含了网络通讯必须的5种信息 Socket例子 { 协议: …

【0基础学Java第九课】-- 抽象类和接口

9. 抽象类和接口 9.1 抽象类9.1.1 抽象类概念9.1.2 抽象类语法9.1.3 抽象类的特性9.1.4 抽象类的作用 9.2 接口9.2.1 接口的概念9.2.2 语法规则9.2.3 接口使用9.2.4 接口特性9.2.5 实现多个接口9.2.6 接口的继承9.2.9 抽象类和接口的区别 9.3 Object类9.3.1 获取对象方法9.3.1 …

【论文精读】DMVSNet

今天读的是一篇发表在ICCV 2023上的文章&#xff0c;作者来自华中科技大学。 文章地址&#xff1a;点击前往 项目地址&#xff1a;Github 文章目录 Abstract1 Introduction2 Relative Work3 Motivation3.1 Estimated bias and interpolated bias3.2 One-sided V.S. Saddle-shap…

Leetcode154. Find Minimum in Rotated Sorted Array II

旋转数组找最小&#xff0c;这次值可以重复 不妨假设你已经做了上一题&#xff0c;题解 上一题的方法1肯定是用不了了&#xff0c;因为不再能完全分成2个不同的部分 所以我们沿着方法2走 如果 > n u m s [ r ] >nums[r] >nums[r]&#xff0c;我们依然可以找右半边 …

SpringBoot 自动配置原理

SpringBoot 自动配置原理 注: 本文使用的springboot版本为 2.7.11 1、SpringBootApplication 字面分析&#xff0c;这个注解是标注一个Spring Boot应用。 Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented Inherited SpringBootConfiguration En…

电路设计之36V 自动断电和防浪涌电路

1. 电路图纸 2. 解释防浪涌功能怎么实现的 1. 首先当电源上电的一瞬间是 电容C1 是相当于短路的。 &#xff08;电容的充电状态。电容充电相当于短路状态&#xff09; 2. 当上电的一瞬间是有 浪涌的。 3.当上电的瞬间有浪涌的&#xff0c;此时电容C1 相当于短路&#xff0c;所…