数据结构进阶篇 之 【二叉树顺序存储(堆)】的整体实现讲解(赋完整实现代码)

在这里插入图片描述

做人要谦虚,多听听别人的意见,然后记录下来,看看谁对你有意见

一、二叉树的顺序(堆)结构及实现

1.二叉树的顺序结构

2.堆的概念及结构

3.堆的实现

3.1 向下调整算法 AdJustDown

3.2 向上调整算法 AdJustUP

3.3 堆的创建

3.3.1 向上建堆
3.3.2 向下建堆
3.3.3 堆的初始化与销毁
3.3.4 堆的插入(压栈)
3.3.5 取堆顶的数据
3.3.6 堆的删除
3.3.7 堆的数据个数
3.3.8 堆的判空

二、堆的完整实现代码

三、完结撒❀

–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–

一、二叉树的顺序(堆)结构及实现

1.二叉树的顺序结构


物理结构:数组
逻辑结构:二叉树

顺序结构存储就是使用数组来存储普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费,而完全二叉树更适合使用顺序结构存储

可能有些同学不太清楚普通二叉树使用数组来存储为什么会造成空间上的浪费,这里给大家讲解一下:
我们使用数组进行二叉树的存储时,父子节点之间需要满足的关系为

parent = (child+1)/2;
leftchild = parent2-1;
rightchild = parent
2+2;
ps:parent指父节点在数组中的下标位置,leftchild指左子节点在数组中的下标位置,rightchild指右子节点在数组中的下标位置

那么对于满二叉树和完全二叉树,我们按照一层一层(层序)往数组中进行存储。
举例如下图所示,大家可以按照下图简单计算验证一下父子之间是否满足父子关系:
在这里插入图片描述

可以知道,对于满二叉树和完全二叉树进行层序存储在数组中,按照下标计算都是满足上面所述的父子关系。

而对于普通二叉树(非满二叉树,非完全二叉树),我们依然按照上面存储进行计算
在这里插入图片描述
可以发现不符合父子节点之间的关系,问题在于2节点的右节点为空,而在存储时对于空节点我们并没有在数组中进行存储记录,相当于在数组中少了一个位置,那么我们如果把空节点加上,如下图:
在这里插入图片描述
这样就满足了父子间的关系,但是对于下标为4的位置并没有存储数据,就造成了空间浪费。

所以,对于普通二叉树我们一般使用链式结构进行存储,避免空间浪费。

现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

2.堆的概念及结构

如果有一个关键码的集合K = {K0,K1,K2,…,Kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:Ki<=K2i+1且Ki<=K2i+2(Ki>=K2i+1且Ki>=K2i+2)i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆的性质:

1.堆中某个节点的值总是不大于或不小于其父节点的值;
2.堆总是一棵完全二叉树;

在这里插入图片描述
堆的兄弟节点(同一父节点的子两个子节点)之间是不论大小的,而对于小堆其父节点的值一定小于子节点,对于大堆其父节点的值一定大于子节点。

3.堆的实现

堆初始化结构:

//堆初始化
void HPInit(HP* php)
{
	assert(php);

	php->a = NULL;
	php->capacity = php->size = 0;
}

在给定一个数组去实现成堆之前我们需要先了解内部实现的核心逻辑

3.1 向下调整算法 AdJustDown

现在我们给出一个数组,逻辑上看做一颗完全二叉树。

int arr[] = {27,15,19,18,28,34,65,49,25,37}

我们通过从根节点开始的向下调整算法可以把它调整成一个小堆
向下调整算法有一个前提:左右子树必须是一个堆,才能调整。
上面数组逻辑上的二叉树可画为:
在这里插入图片描述
可以看出来,根节点27影响了整体的小堆结构,那么我们如何将其转变为小堆呢?
在这里插入图片描述

(制作不是很好大家将就着看看就行)
按照上面图片显示的流程,我们在逻辑上就把之前的二叉树变成了小堆排序,而其逻辑实现思想就是向下调整。

向下调整

再强调一边:
向下调整算法有一个前提:左右子树必须是一个堆,才能调整。

从根开始,比较其子节点的大小,如果为大堆排序就将父节点与子节点中较大的节点交换,如果为小堆就将父节点与子节点中较小的节点交换。交换完毕继续重复以上逻辑,直到父节点大于子节点(大堆)或是父节点小于子节点(小堆)即可完成堆排序。

代码实现:

void Swap(HPDataType* px, HPDataType* py)
{
	HPDataType tmp = *px;
	*px = *py;
	*py = tmp;
}

//向下调整O(logN)
void AdJustDown(HPDataType* a, int n, int parent)
{
	//从左孩子开始,child为小孩子那个
	 int child = parent * 2 + 1;

	 while (child<n)
	 {
		 
		 if (child + 1 < n && a[child] > a[child + 1])
		 {
			++child;
		 }

		 if (a[child] < a[parent])//小堆<,大堆>
		 {
			 Swap(&a[parent], &a[child]);
			 parent = child;
			 child = child * 2 + 1;
		 }
		 else
		 {
			 break;
		 }
	 }
}

3.2 向上调整算法 AdJustUP

在一个二叉树的数组中如果我们尾插了一个数据,可能就导致结构不再是堆。

所以我们如果是在现有的一个堆里进行数据尾插存储,那么我们要保证数据插入后还是堆,这时一般使用向上调整算法。

下面我们给出一个数组,请画出其逻辑结构二叉树:

int arr[] = {10,15,56,25,30,70}

二叉树:

在这里插入图片描述
如果我将5尾插在数组当中,那么就相当于是将56节点的右孩子连了一个5节点:
在这里插入图片描述
这显然已经不是小堆了,调整逻辑如下:
在这里插入图片描述
这就是向上调整的整体逻辑:

如果是进行小堆排序,将尾节点值与其父节点的值进行比较,如果小于父节点就交换,如果进行大堆,那就判断子节点是否大于父节点,若是大于就交换。

代码实现:

void Swap(HPDataType* px, HPDataType* py)
{
	HPDataType tmp = *px;
	*px = *py;
	*py = tmp;
}

//向上调整 O(logN)
void AdJustUP(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;

	//while (1)严格来说不行
	while(child>0)
	{
		if (a[child] < a[parent])//小堆<,大堆>
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (parent - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

向下调整算法和向上调整算法的时间复杂度都为O(logN),大家感兴趣可以算一下。

3.3 堆的创建

向上调整和向下调整都是基于已经形成了堆上面,那么如果随便给一个本就不是堆的数组,我们该如何进行建堆呢?

3.3.1 向上建堆

下面我们给出一个数组,这个数组逻辑上可以看做一颗完全二叉树,但是还不是一个小堆,现在我们通过算法,把它构建成一个小堆。

int a[] = {536821};

根节点左右子树不是小堆,我们怎么调整呢?

这里我们从根的左孩子节点开始向上调整,根据数组存储顺序向后以此执行,直到最后一个节点为止。

其二叉树为:
在这里插入图片描述
调整逻辑:
在这里插入图片描述
从根节点的子节点开始,进行向上调整,一次调整完毕将子节点对应数组下标加1进入下一个节点进行向上调整,直到除了根的所有节点都调整完毕,二叉树便变成了堆。

代码实现:

//向上调整 O(logN)
void AdJustUP(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;

	//while (1)严格来说不行
	while(child>0)
	{
		if (a[child] < a[parent])//小堆<,大堆>
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (parent - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

//初始化建堆
void HPInitArray(HP* php, HPDataType* a, int n)
{
	assert(php);

	php->a = (HPDataType*)malloc(sizeof(HPDataType) * n);
	if (php->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	memcpy(php->a, a, sizeof(HPDataType) * n);
	php->size = php->capacity = n;

	//向上建堆 O(N*logN)
	for (int i = 1; i < php->size; i++)
	{
		AdjustUp(php->a, i);
	}
}
3.3.2 向下建堆

向下建堆就是根据向下调整的逻辑进行。

我们把二叉树分为其根和子树,再把子树分为其根和子树,将每一个分好的子树都进行向下调整,直到叶子节点为止。

我们还拿上面数组为例:

int a[] = {536821};

这里我们从倒数的第一个非叶子节点的子树开始调整,一直调整到根节点的树,就可以调整成小堆

调整逻辑:在这里插入图片描述
代码实现:

//向下调整O(logN)
void AdJustDown(HPDataType* a, int n, int parent)
{
	//从左孩子开始,child为小孩子那个
	 int child = parent * 2 + 1;

	 while (child<n)
	 {
		 
		 //假设法选出左右节点中大/小的节点
		 if (child + 1 < n && a[child] > a[child + 1])
		 {
			++child;
		 }

		 if (a[child] < a[parent])//小堆<,大堆>
		 {
			 Swap(&a[parent], &a[child]);
			 parent = child;
			 child = child * 2 + 1;
		 }
		 else
		 {
			 break;
		 }
	 }
}

//初始化建堆
void HPInitArray(HP* php, HPDataType* a, int n)
{
	assert(php);

	php->a = (HPDataType*)malloc(sizeof(HPDataType) * n);
	if (php->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	memcpy(php->a, a, sizeof(HPDataType) * n);
	php->size = php->capacity = n;
		//向下建堆 O(N)
	for (int i = (php->size - 1 - 1) / 2; i >= 0; i--)
	{
		AdJustDown(php->a, php->size, i);
	}
}

向上建堆和向下建堆的时间复杂度分别为O(N*logN),O(N)。
因为向下建堆的时间复杂度小,所以我们在实际工作中进行建堆一般是选择向下建堆

3.3.3 堆的初始化与销毁

在数据结构中,创建任何结构,都需要对其进行初始化和销毁。

代码实现:

//堆初始化
void HPInit(HP* php)
{
	assert(php);

	php->a = NULL;
	php->capacity = php->size = 0;
}

//堆销毁
void HPDestory(HP* php)
{
	assert(php);

	free(php->a);
	php->a = NULL;
	php->capacity = php->size = 0;
}
3.3.4 堆的插入(压栈)

插入一个数到数组的尾上,再进行向上调整算法,直到满足堆。
代码实现:

//向上调整 O(logN)
void AdJustUP(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;

	//while (1)严格来说不行
	while(child>0)
	{
		if (a[child] < a[parent])//小堆<,大堆>
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (parent - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

//压栈 O(logN)
void HPPush(HP* php, HPDataType x)
{
	assert(php);

	//判断空间是否足够
	if (php->size == php->capacity)
	{
		int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		php->a = tmp;
		php->capacity = newcapacity;
	}

	php->a[php->size] = x;
	php->size++;

	//数据尾插向上调整
	AdJustUP(php->a, php->size-1);
}

3.3.5 取堆顶的数据

在建好的堆中返回其根部数据。
代码实现:

//返回根数据
HPDataType HPTop(HP* php)
{
	assert(php);
	assert(php->size);

	return php->a[0];
}

3.3.6 堆的删除

删除堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。

代码实现:

//向下调整O(logN)
void AdJustDown(HPDataType* a, int n, int parent)
{
	//从左孩子开始,child为小孩子那个
	 int child = parent * 2 + 1;

	 while (child<n)
	 {
		 
		 if (child + 1 < n && a[child] > a[child + 1])
		 {
			++child;
		 }

		 if (a[child] < a[parent])//小堆<,大堆>
		 {
			 Swap(&a[parent], &a[child]);
			 parent = child;
			 child = child * 2 + 1;
		 }
		 else
		 {
			 break;
		 }
	 }
}

//删除根数据O(logN)
void HPPop(HP* php)
{
	assert(php);
	assert(php->size);

	//将根数据与最后一个子叶交换,再删除最后一个数据
	Swap(&php->a[0], &php->a[php->size-1]);
	php->size--;

	//向下调整
	AdJustDown(php->a, php->size, 0);
}
3.3.7 堆的数据个数

代码实现:

int HeapSize(HP* php)
{
	assert(php);

	return php->size;
}
3.3.8 堆的判空

代码实现:

//判断堆是否为空
bool HPEmpty(HP* php)
{
	assert(php);

	return php->size == 0;
}

二、堆的完整实现代码

Heap.h:

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

typedef int HPDataType;

typedef struct Heap
{
	HPDataType* a;
	int size;
	int capacity;
}HP;

//小堆

//堆初始化
void HPInit(HP* php);
//初始化建堆
void HPInitArray(HP* php, HPDataType* a, int n);

//堆销毁
void HPDestory(HP* php);

//压栈
void HPPush(HP* php, HPDataType x);

//返回根数据
HPDataType HPTop(HP* php);

//删除根数据
void HPPop(HP* php);

//堆的数据个数
int HPSize(HP* php);

//判断堆是否为空
bool HPEmpty(HP* php);

Heap.c:

#include "Heap.h"

//堆初始化
void HPInit(HP* php)
{
	assert(php);

	php->a = NULL;
	php->capacity = php->size = 0;
}

//堆销毁
void HPDestory(HP* php)
{
	assert(php);

	free(php->a);
	php->a = NULL;
	php->capacity = php->size = 0;
}

void Swap(HPDataType* px, HPDataType* py)
{
	HPDataType tmp = *px;
	*px = *py;
	*py = tmp;
}

//向上调整 O(logN)
void AdJustUP(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;

	//while (1)严格来说不行
	while(child>0)
	{
		if (a[child] < a[parent])//小堆<,大堆>
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (parent - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

//压栈 O(logN)
void HPPush(HP* php, HPDataType x)
{
	assert(php);

	//判断空间是否足够
	if (php->size == php->capacity)
	{
		int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		php->a = tmp;
		php->capacity = newcapacity;
	}

	php->a[php->size] = x;
	php->size++;

	//数据尾插向上调整
	AdJustUP(php->a, php->size-1);
}

//返回根数据
HPDataType HPTop(HP* php)
{
	assert(php);
	assert(php->size);

	return php->a[0];
}

//向下调整O(logN)
void AdJustDown(HPDataType* a, int n, int parent)
{
	//从左孩子开始,child为小孩子那个
	int child = parent * 2 + 1;

	while (child < n)
	{

		if (child + 1 < n && a[child] > a[child + 1])
		{
			++child;
		}

		if (a[child] < a[parent])//小堆<,大堆>
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

//删除根数据O(logN)
void HPPop(HP* php)
{
	assert(php);
	assert(php->size);

	//将根数据与最后一个子叶交换,再删除最后一个数据
	Swap(&php->a[0], &php->a[php->size-1]);
	php->size--;

	//向下调整
	AdJustDown(php->a, php->size, 0);
}

int HeapSize(HP* php)
{
	assert(php);

	return php->size;
}

//判断堆是否为空
bool HPEmpty(HP* php)
{
	assert(php);

	return php->size == 0;
}

//初始化建堆
void HPInitArray(HP* php, HPDataType* a, int n)
{
	assert(php);

	php->a = (HPDataType*)malloc(sizeof(HPDataType) * n);
	if (php->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	memcpy(php->a, a, sizeof(HPDataType) * n);
	php->size = php->capacity = n;

	//向上建堆 O(N*logN)
	/*for (int i = 1; i < php->size; i++)
	{
		AdjustUp(php->a, i);
	}*/

	//向下建堆 O(N)
	for (int i = (php->size - 1 - 1) / 2; i >= 0; i--)
	{
		AdJustDown(php->a, php->size, i);
	}
}

//建堆排序

//排序
// 升序
//小堆时间复杂度太大O(N^2),用大堆进行排序O(N*logN)
//大堆

//升序  大堆 O(N*logN)
//降序  小堆 O(N*logN)
void HeapSort(HPDataType* a, int n)
{
	//根据数组直接建堆 O(N)
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdJustDown(a, n, i);
	}

	//交换根和尾的位置,删除尾,再向上调整 O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdJustDown(a, end, 0);
		--end;
	}
}

三、完结撒❀

如果以上内容对你有帮助不妨点赞支持一下,以后还会分享更多编程知识,我们一起进步。
最后我想讲的是,据说点赞的都能找到漂亮女朋友❤
在这里插入图片描述

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

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

相关文章

细讲内存四区

目录 1.1数据类型本质分析 1.1.1数据类型概念 1.1.2数据类型的本质 1.1.3给类型起别名--typedef 1.1.4void类型 1.2变量的本质分析 1.2.1变量的概念 1.2.2变量的本质 1.3程序的内存四区模型 1.3.1栈区和堆区 1.3.2静态区 1.4函数的调用模型 1.5函数调用变main量传…

AcWing 1413. 矩形牛棚(每日一题)

原题链接&#xff1a;1413. 矩形牛棚 - AcWing题库 作为一个资本家&#xff0c;农夫约翰希望通过购买更多的奶牛来扩大他的牛奶业务。 因此&#xff0c;他需要找地方建立一个新的牛棚。 约翰购买了一大块土地&#xff0c;这个土地可以看作是一个 R 行&#xff08;编号 1∼R&…

在Arduino IDE中使用文件夹组织源文件和头文件

在Arduino IDE中使用文件夹组织源文件和头文件 如果你是一名Arduino爱好者&#xff0c;你可能会发现随着项目的复杂度增加&#xff0c;代码的管理变得越来越困难。在Arduino IDE中&#xff0c;你可以通过使用文件夹来更好地组织你的源文件和头文件&#xff0c;使得代码更加清晰…

Python 妙用运算符重载——玩出“点”花样来

目录 运算符重载 主角点类 魔法方法 __getitem__ __setitem__ __iter__ __next__ __len__ __neg__ __pos__ __abs__ __bool__ __call__ 重载运算符 比较运算符 相等 不等 ! 大于和小于 >、< 大于等于和小于等于 >、< 位运算符 位与 & 位…

win11 环境配置 之 Jmeter(JDK17版本)

一、安装 JDK 1. 安装 jdk 截至当前最新时间&#xff1a; 2024.3.27 jdk最新的版本 是 官网下载地址&#xff1a; https://www.oracle.com/java/technologies/downloads/ 建议下载 jdk17 另存为到该电脑的 D 盘下&#xff0c;新建jdk文件夹 开始安装到 jdk 文件夹下 2. 配…

基于reactor模式的简易web服务器

文章目录 基于reactor模式的tcp服务器什么是reactor模式&#xff1f;实现步骤 修改recv_cb逻辑变成web服务器web服务器性能测试&#xff08;wrk工具的使用&#xff09; 基于reactor模式的tcp服务器 本文基于上篇的简易tcp通信服务器基础 上进行封装&#xff0c;写出使用epoll的…

递归方法的理解

递归方法调用 &#xff1a;方法自己调用自己的现象就称为递归。 递归的分类 : 直接递归、间接递归。 直接递归&#xff1a;方法自身调用自己 public void methodA (){ methodA (); } 间接递归&#xff1a;可以理解为A()方法调用B()方法&#xff0c;B()方法调用C()方法&am…

fastllm在CPU上推理ChatGLM3-6b,即使使用CPU依然推理速度很快,就来看这篇文章

介绍: GitHub - ztxz16/fastllm: 纯c++的全平台llm加速库,支持python调用,chatglm-6B级模型单卡可达10000+token / s,支持glm, llama, moss基座,手机端流畅运行纯c++的全平台llm加速库,支持python调用,chatglm-6B级模型单卡可达10000+token / s,支持glm, llama, moss基…

【实验报告】--基础VLAN

【VLAN实验报告】 一、项目背景 &#xff08;为 Jan16 公司创建部门 VLAN&#xff09; Jan16 公司现有财务部、技术部和业务部&#xff0c;出于数据安全的考虑&#xff0c;各部门的计算机需进 行隔离&#xff0c;仅允许部门内部相互通信。公司拓扑如图 1 所示&#xff0c; …

安装uim-ui插件不成功,成功解决

安装&#xff1a;这种安装&#xff0c;umi4 不支持&#xff0c;只有umi3才支持。而我发现官网现在默认使用的umi4。 yarn add umijs/preset-ui -D 解决&#xff1a;更改umi版本重新安装umi3 npm i ant-design/pro-cli3.1.0 -g #使用umi3 (指定umi3版本) pro create user-ce…

什么是防火墙,部署防火墙有什么好处?

与我们的房屋没有围墙或界限墙一样&#xff0c;没有防护措施的计算机和网络将容易受到黑客的入侵&#xff0c;这将使我们的网络处于巨大的风险之中。因此&#xff0c;就像围墙保护我们的房屋一样&#xff0c;虚拟墙也可以保护和安全我们的设备&#xff0c;使入侵者无法轻易进入…

WEB APIS知识点案例总结

随机点名案例 业务分析: 点击开始按钮随机抽取数组中的一个数据,放到页面中点击结束按钮删除数组当前抽取的一个数据当抽取到最后一个数据的时候,两个按钮同时禁用(只剩最后一个数据不用抽了) 核心:利用定时器快速展示,停止定时器结束展示 <!DOCTYPE html> <html…

【送书福利第六期】:《AI绘画教程:Midjourney使用方法与技巧从入门到精通》

文章目录 一、《AI绘画教程&#xff1a;Midjourney使用方法与技巧从入门到精通》二、内容介绍三、作者介绍&#x1f324;️粉丝福利 一、《AI绘画教程&#xff1a;Midjourney使用方法与技巧从入门到精通》 一本书读懂Midjourney绘画&#xff0c;让创意更简单&#xff0c;让设计…

小米SU7 我劝你再等等

文 | AUTO芯球 作者 | 李逵 我必须承认我一时没忍住 犯错了 我不会被我老婆打吧 感觉有点慌呀 这不前两天 我刚提了台问界M9嘛 但是昨晚看小米汽车发布会 是真的被雷总感染到了 真的没忍住 我又冲了台小米SU7 Pro版 本来我是准备抢创始版的 结果1秒钟时间 点进去就…

Java基础语法(六)| 类和对象

前言 Hello&#xff0c;大家好&#xff01;很开心与你们在这里相遇&#xff0c;我是一个喜欢文字、喜欢有趣的灵魂、喜欢探索一切有趣事物的女孩&#xff0c;想与你们共同学习、探索关于IT的相关知识&#xff0c;希望我们可以一路陪伴~ 1. 面向对象概述 1.1 什么是面向对象 Ja…

【毕业论文】| 基于Unity3D引擎的冒险游戏的设计与实现

&#x1f4e2;博客主页&#xff1a;肩匣与橘 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由肩匣与橘编写&#xff0c;首发于CSDN&#x1f649; &#x1f4e2;生活依旧是美好而又温柔的&#xff0c;你也…

字符串(KMP)

P3375 【模板】KMP - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; #define ll long long const int N1e6100; int n0,m; char s1[N]; char s2[N];…

【MATLAB源码-第22期】基于matlab的手动实现的(未调用内置函数)CRC循环码编码译码仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 循环码是线性分组码的一种&#xff0c;所以它具有线性分组码的一般特性&#xff0c;此外还具有循环性。循环码的编码和解码设备都不太复杂&#xff0c;且检(纠)错能力强。它不但可以检测随机的错误&#xff0c;还可以检错突发…

2024年大广赛联通沃派命题解析:赛题内容一览

2024大广赛又又又又又出新命题了&#xff0c;它就是助力青少年积极向上&#xff0c;乐观自信&#xff0c;探享多彩人生的5G时代潮牌——联通沃派&#xff0c;让我们来看看命题详情吧&#xff01; 联联通沃派是中国联通面向青少年群体推出的客户品牌&#xff0c;契合目标群体特…

数据结构 - 图

参考链接&#xff1a;数据结构&#xff1a;图(Graph)【详解】_图数据结构-CSDN博客 图的定义 图(Graph)是由顶点的有穷非空集合 V ( G ) 和顶点之间边的集合 E ( G ) 组成&#xff0c;通常表示为: G ( V , E ) &#xff0c;其中&#xff0c; G 表示个图&#xff0c; V 是图 G…