特殊二叉树——堆

news2025/1/11 2:16:29

🌈一、堆的基本概念

1.堆:非线性结构,是完全二叉树
2.堆分为大堆和小堆。
大堆:树中任意一个父亲都大于等于孩子,根节点值大于等于其所有子孙节点的值。
小堆:树中任意一个父亲都小于等于孩子,根节点值小于等于其所有子孙节点的值。
3.“同辈”即同一层数据间的大小顺序不做要求。
4.堆的物理结构即实际内存中存储的结构是顺序表,但逻辑结构是树。
在这里插入图片描述5.堆特性:堆中最有用的数据是堆的根节点。小堆的根是整棵树的最小值,大堆的根是整棵树的最大值.
6.堆的用途:①topk问题 ②堆排序

🌈二、实现一个小堆(大堆同理)

☀️(1)头文件test.h:

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int HpDataType;
typedef struct  {
	HpDataType* a;
	int size;
	int capacity;
}HP;
void Swap(HpDataType* p1, HpDataType* p2);
void AdjustUp(HpDataType* php, int x);
void HeapPrint(HP* php);
void HeapInit(HP* php);
void HeapDestroy(HP* php);
void HeapPush(HP* php, HpDataType x);
void AdjustDown(HpDataType* a, int n, int parent);
void HeapPop(HP* php);
HpDataType HeapTop(HP* php);
bool HeapEmpty(HP* php);

☀️(2)函数实现heap.c:

🎈1.初始化、销毁函数:

#define _CRT_SECURE_NO_WARNINGS
#include"test.h"
void HeapInit(HP* php) {
	assert(php);
	php->a = NULL;
	php->size = 0;
	php->capacity = 0;
}
void HeapDestroy(HP* php) {
	assert(php);
	free(php->a);
	php->a = NULL;
	php->size = php->capacity = 0;
}

🎈2.打印、交换数值函数:

void Swap(HpDataType* p1, HpDataType* p2) {
	HpDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
void HeapPrint(HP* php) {
	assert(php);
	for (int i = 0;i < php->size;i++) {
		printf("%d ", php->a[i]);
	}
	printf("\n");
}

Swap函数细节分析:
Swap函数:用来交换父亲节点和孩子节点的值:
在这里插入图片描述

🎈3.插入、向上调整函数:

现在有一个堆,对其插入一个值:
插入位置:插入到根节点会破坏堆的结构;插入到树的中间部分的话我怎么知道哪里是中间部分,难不成还要先算一下树的大小?只能插入到最高层的末尾位置,即数组的末尾处,然后一层一层向上调整成一个正确的堆。
步骤一:首先需要判断该堆的容量是否足够插入一个节点,容量不够就扩容。
步骤二:根据插入的值判断是否需要对树进行调整。
eg:该情况下,若插入90,不需要对树进行调整:
在这里插入图片描述
若插入50,需要对树进行调整:
在这里插入图片描述
调整部位:右子树即50的“祖先”,不调整左子树15及其“子代”。
如何调整:一层一层地和“父亲”换位置,直到符合大小排序。
调整完的样子:
在这里插入图片描述

代码部分:


void AdjustUp(HpDataType* a, int child) {
	int parent = (child - 1) / 2;
	//为什么要用循环?
	//因为不止调整一次,有可能调整好多次直到child走到了根节点
	while (child > 0) {
		if (a[child] < a[parent]) {
			swap(&a[child], &a[parent]);
			//为什么还要加取地址符号&?
			//因为要对该空间的值进行更改,传值调用不会改变空间上的值,只有传地址才行
			child = parent;
			parent = (child - 1) / 2;
		}
		else
			break;
	}
}
void HeapPush(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, sizeof(HpDataType) * newCapacity);
		if (tmp == NULL) {
			perror("realloc fail");
			exit(-1);
		}
		php->a = tmp;
		php->capacity = newCapacity;
	}
	php->a[php->size] = x;
	php->size++;
	//步骤二:调整
	//命名含义:每次插入的位置都是最后一层最右边的节点,
	//调整过程是一层一层向上进行的,因此叫adjust up
	AdjustUp(php->a, php->size - 1);
	//函数参数:
	//参数一:需要知道在那棵树中调整=>数组指针即a;
	//参数二:需要知道调整哪个节点=>下标即size-1;
}

细节分析:
1.关于AdjustUp函数名和参数:
在这里插入图片描述
2.关于AdjustUp函数内部:
在这里插入图片描述

🎈4.删除、向下调整函数:

删除位置:基于堆的特性,堆中最有用的数据是根上的数据,因此删除也是删除根的数据。
如何删除:
👻错误方法:直接挪动后面的数据覆盖,这样会破坏堆结构,得到的不一定是堆,如图:在这里插入图片描述
挪动覆盖根,关系全乱了,原先的兄弟关系被迫变成了父子或长辈晚辈关系,不一定稳定(不一定符合大小顺序),就不一定是堆了。
👻正确方法:最下面一层的最后一个数8和根位置的数据2交换,然后删除掉最后一层最后一个数据(–size就删除了),然后从根节点向下调整。下一层的最小的数据和根数据交换,直到走到最下面一层就调整成了正确的堆结构。每删除(pop)一次就能得到堆中最小的数。
👻背后原理:不破坏树原本的结构,左右子树依旧是小堆。
在这里插入图片描述
注:
向下调整前提:左右子树是堆;
向上调整前提:前面的数据是堆。

代码实现:

void AdjustDown(HpDataType* a, int n, int parent) {
	int child = parent * 2 + 1;
	//while循环作用:1.实现从上到下一层一层调整 
	//2.child>n时说明已经调整到最后一层,停止循环
	while (child < n) {
		//当有两个孩子时,需要选出较小的孩子与父节点比较
		//如果只有一个孩子,那child下标就是parent*2+1
		if (child + 1 < n && a[child + 1] < a[child]) {
			++child;
		}
		if (a[child] < a[parent]) {
			Swap(&a[child], &a[parent]);
			//继续往下调整
			parent = child;
			child = parent * 2 + 1;
		}
		//只要某一层的孩子节点值大于父节点值,就停止循环,
		//这是基于除了根节点其他地方都符合堆结构的前提
		else
			break;
	}
}
void HeapPop(HP* php) {
	assert(php);
	assert(php->size > 0);
	swap(&php->a[0], &php->a[php->size - 1]);
	--php->size;
	AdjustDown(php->a, php->size, 0);
	//参数分析:
	//参数一:结构体中的数组指针,指向堆
	//参数二:堆的大小,计算出的孩子序号数与堆大小进行比较就可以知道是否有该孩子
	//参数三:父节点下标,从该位置开始向下调整
}

细节分析(关于AdjustDown函数):
①参数分析:
在这里插入图片描述

②while循环作用:
在这里插入图片描述

③孩子节点可能有一个或两个,如何选出值较小的那个?
在这里插入图片描述
当没有“child+1<n”条件时,如果父节点只有一个左孩子,那么a[child+1]就会造成越界访问。

④向上调整或向下调整的前提是除了被调整节点,其他部位都符合堆,即左右子树是堆:
在这里插入图片描述

🎈5.根节点函数、判空函数:

HpDataType HeapTop(HP* php) {
	assert(php);
	assert(php->size > 0);
	return php->a[0];
}
bool HeapEmpty(HP* php) {
	assert(php);
	return php->size == 0;
}

☀️(3)测试test.c:

🎈1.测试插入:

测试思路:一个数组本身不是堆,但当我将每一个元素都push进去后,它就变成了堆。通过打印看是否建堆成功。

#define _CRT_SECURE_NO_WARNINGS
#include"test.h"
int main() {
	int a[] = { 65,100,70,32,50,60 };
	HP hp;
	HeapInit(&hp);
	for (int i = 0;i < sizeof(a) / sizeof(a[0]);i++) {
		HeapPush(&hp, a[i]);
	}
	HeapPrint(&hp);
	HeapDestroy(&hp);
	return 0;
}

打印结果:
在这里插入图片描述
从物理结构转变为逻辑结构:建堆成功。
在这里插入图片描述

🎈2.测试从小到大对堆中的值排序:

测试思路:先通过push函数将数组建成堆结构,然后通过top函数得到根节点值(最小值),最后pop掉根节点,将剩下的数调整成堆结构,继续得到根节点值(次小值)。

#define _CRT_SECURE_NO_WARNINGS
#include"test.h"
int main() {
	int a[] = { 65,100,70,32,50,60 };
	HP hp;
	HeapInit(&hp);
	for (int i = 0;i < sizeof(a) / sizeof(a[0]);i++) {
		HeapPush(&hp, a[i]);
	}
	HeapPrint(&hp);
	while (!HeapEmpty(&hp)) {
		printf("%d ", HeapTop(&hp));
		HeapPop(&hp);
	}
	HeapDestroy(&hp);
	return 0;
}

打印结果:
在这里插入图片描述
由此可以看出,将一组数据建堆是对改组数据进行粗略的排序;将堆的根一个一个取出才能得到准确的大小关系。

思考:如何实现大堆?

AdjustUp函数和AdjustDown函数中,把if中的大于小于号换一下即可。

🌈三、堆结构基础上实现堆排序

给出一个数组,将数组中的数据一个一个放进搭建好的小堆结构中,再将每次pop出来的最小值(根节点数据)从左到右放进原数组,从而排成升序。

☀️HeapSort函数:

void HeapSort(int* a, int n) {
	HP hp;
	HeapInit(&hp);
	for (int i = 0;i < n;i++) {
		HeapPush(&hp, a[i]);
	}
	int i = 0;
	while (!HeapEmpty(&hp)) {
		a[i++] = HeapTop(&hp);
		HeapPop(&hp);
	}
	HeapDestroy(&hp);
}

测试将一组数排成升序:

int main() {
	int a[] = { 2,3,5,7,4,6,8,65,100,70,32,50,60 };
	HeapSort(a, sizeof(a) / sizeof(a[0]));
	return 0;
}

结果(通过监视看内存):
在这里插入图片描述
在这里插入图片描述
思考:如果要将改组数据排成降序呢?
法一:得到pop出来的最小值(根节点)后,从原数组最后面往前放置。
法二:建大堆,将每次pop出的最大值(根节点)从前往后放进原数组。
👻注:这种写法的缺陷:
1.需要先搭建一个完整的堆结构:先初始化,再有插入向上调整,删除向下调整等等;
2.空间复杂度的消耗:被排序的原数组占据了一部分空间,将原数组的值插入进堆中又占用了相同大小的空间,造成空间浪费。

🌈四、无堆结构,在数组上原地建堆

☀️法一:向上调整建堆

1.思路:从前往后依次将数组的值插入进堆,并向上调整。不需要初始化与销毁,只需要AdjustUp函数。
2.代码:
heap.c函数文件:

void AdjustUp(int* a, int child) {
	int parent = (child - 1) / 2;
	while (child > 0) {
		if (a[parent] > a[child]) {
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
			break;
	}
}
void Swap(int* a, int* b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void HeapSort(int* a, int n) {
	for (int i = 0;i < n;i++) {
		AdjustUp(a, i);
	}
}

test.c测试文件:
测试将一组数组中的无序的数排成小堆

#define _CRT_SECURE_NO_WARNINGS
#include"test.h"
int main() {
	int a[] = { 70,65,100,32,50,60 };
	HeapSort(a, sizeof(a) / sizeof(int));
	for (int i = 0;i < sizeof(a) / sizeof(int);i++) {
		printf("%d ", a[i]);
	}
}

测试结果:
在这里插入图片描述
原地建堆成功。

☀️法二:向下调整建堆

1.思路:从最后一个节点的父节点(倒数第一个父节点)开始,向下调整至正确大小顺序;然后指针向前移动,指向倒数第二个父节点,向下调整;直至从根节点向下调整。
2.代码:
heap.c函数文件:

void AdjustDown(int* a, int size,int i) {
	int parent = i;
	int child = parent * 2 + 1;
	while (child < size) {
		if (child + 1 < size && a[child] > a[child + 1]) {
			child++;
		}
		if (a[parent] > a[child]) {
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}
void Swap(int* a, int* b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void HeapSort(int* a, int n) {
	for (int i = (n - 1 - 1) / 2;i >= 0;i--) {
		AdjustDown(a, n, i);
	}
}

细节:
为何有child+1<size,没有的话会怎样?
在这里插入图片描述

堆的节点不一定都有两个孩子,如果倒数第一个父节点只有一个左孩子,则child+1就越界了。因此要确保有两个孩子的情况下才能比较两个孩子谁大谁小,只有一个孩子时,child就储存这一个孩子节点的下标。
test.c测试文件:
测试将一组数组中的无序的数排成小堆

#define _CRT_SECURE_NO_WARNINGS
#include"test.h"
int main() {
	int a[] = { 70,65,100,32,50,60 };
	HeapSort(a, sizeof(a) / sizeof(int));
	for (int i = 0;i < sizeof(a) / sizeof(int);i++) {
		printf("%d ", a[i]);
	}
}

测试结果:
在这里插入图片描述

☀️比较向上和向下调整建堆

1.计算向下调整建堆时间复杂度:O(N)=N-logN
在这里插入图片描述
在这里插入图片描述

2.向上调整建堆时间复杂度:N*logN
在这里插入图片描述
在这里插入图片描述
3.比较结果:向下调整时间复杂度更低,效率更高。
更直观的理解方法:对于向上调整而言,节点最多的那一层(最高层)需要向上调整的次数最多(有h层就调整h-1次),即大数乘大数;对于向下调整而言,节点最多的那一层(最高层)需要向下调整的次数最少(最高层调整0次),即大数乘小数。因此相比较而言,向下调整建堆时间复杂度更低。

🌈五、无堆结构,对数组进行堆排序

思路:先通过向上或向下调整建堆,在没有堆结构的基础上让数组先成为堆,再通过pop的思想每次得到根节点,即为当前的最大值(最小值)。步骤为:建堆->pop。

☀️升序降序分别建什么堆?

假设现在要将一组数排成升序:
在这里插入图片描述
👻如果在已经有堆结构的基础上排升序,法一是建小堆,pop出来的数是从小到大的,从左到右排列在新开辟的数组空间中,从而将数组排成升序。法二是建大堆,pop出来的数是从大到小的,只需要从空间的右边往左边排,即可排成降序。

👻现在没有堆结构,并且直接在原数组上建堆,意味着不可以新开辟空间,此时需要仔细斟酌排序对应建什么堆:
🎈1.错误方法:排升序建小堆:
第一步:建成小堆后,得到物理结构与逻辑结构,如下:
在这里插入图片描述
在这里插入图片描述
第二步:pop出根节点,得到最小值32,并且刚好在数组最左边。
第三步:用剩下的数据得到次小值。
问题来了:如何排除掉第一个数据?
如果直接移动指针,将下标为1的节点作为根节点,则有破坏堆结构的风险,如图:
在这里插入图片描述
如果将剩下的数重新建堆,则代价太大。
因此排升序不可以建小堆。
🎈2.正确方法:建大堆,每次pop出的数和数组最右边一个数交换,再向下调整从而得出次大的数,从右往左放置从大到小的数,从而排成升序。
具体过程如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
🎈3.结论:排升序,建大堆;排降序,建小堆。
🎈4.为何有堆结构时可以随意建大小堆,无堆结构时有限制?
本质上是因为:有堆结构时,可以将数据从原先的混乱数组中转移到一片新的空间,只需要将大小堆和放置先后顺序匹配就可排成任意顺序(排升序:如果建大堆,从右往左放,如果建小堆,从左往右放;排降序:如果建大堆,从左往右放,如果建小堆,从右往左放)。无堆结构时,从混乱的一组数据到堆结构再到有序结构,始终是在同一块空间上进行操作的,为了不破坏堆结构,只能用pop和向下调整的方式,因此对什么时候建什么堆有限制(升序建大堆,降序建小堆)。

☀️代码(将数组排成降序)

方法:让数组中的数据一个一个插入到堆的最后面,再向上调整,从而建堆。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void Swap(int* a, int* b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void AdjustDown(int* a, int size, int i) {
	int parent = i;
	int child = parent * 2 + 1;
	while (child < size) {
		if (child + 1 < size && a[child] > a[child + 1]) {
			child++;
		}
		if (a[parent] > a[child]) {
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}

void HeapSort(int* a, int n) {
	for (int i = (n - 1 - 1) / 2;i >= 0;i--) {
		AdjustDown(a, n, i);
	}
	int end = n - 1;
	while (end >= 0) {
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		end--;
	}
}
int main() {
	int a[] = { 70,65,100,32,50,60 };
	HeapSort(a, sizeof(a) / sizeof(int));
	for (int i = 0;i < sizeof(a) / sizeof(int);i++) {
		printf("%d ", a[i]);
	}
}

测试结果:
在这里插入图片描述

☀️应用:TopK问题

👻问题背景:一共10000个数,要找出最大的前10个。
👻程序设计:
1.随机生成10000个值小于10000的数
2.随机10挑个数改成大于10000的值(为了方便检查测试结果,如果最终得到的10个数就是这些大于10000的值的话,则说明筛选成功)
👻解决方案:
先对这10000个数的前10个数建小堆,然后后面的9990个数依次和堆顶数据比较,大于堆顶数据的话则顶替这个堆顶数据进堆。
问:为何要对前10个数据建小堆,建大堆会怎样?
答:假设这10000个数中最大的数恰好在前10个中,则建了大堆后,根节点一开始的值就是最大值,后面的9990个数就无法进堆,最终只有根节点的最大值是准确的,剩下的9个值找不到。而建小堆的话,最大的前10个数来了都可以畅通无阻的进堆,然后再向下调整至正确位置,最终堆中剩下的数就是最大的前10个。

代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include<time.h>
#include<stdlib.h>
void Swap(int* a, int* b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void AdjustDown(int* a, int k, int parent) {
	int child = parent * 2 + 1;
	while (child<k) {
		if (child + 1 < k && a[child + 1] < a[child]) {
			child++;
		}
		if (a[parent] > a[child]) {
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else {
			break;
		}
	}
}
void PrintTopK(int* a, int n, int k) {
	//对前10个数据建小堆
	for (int i = (k-2)/2;i >=0 ;i--) {
		AdjustDown(a, k, i);
	}
	//将剩下9990个数据依次与堆顶元素比较
	//若大于堆顶,则替换堆顶进堆,并向下调整
	for (int i = 0;i < n - k;i++) {
		if (a[k + i] > a[0]) {
			Swap(&a[k + i], &a[0]);
			AdjustDown(a, k, 0);
		}
	}
	//将前k个数据打印出来
	for (int i = 0;i < k;i++) {
		printf("%d ", a[i]);
	}
}
void TeatTopK() {
	int n = 10000;
	int k = 10;
	srand(time(0));
	int* a = (int*)malloc(sizeof(int) * n);
	for (size_t i = 0;i < n;i++) {
		a[i] = rand() % 10000;
	}
	a[10] = 10001;
	a[29] = 10002;
	a[300] = 10003;
	a[790] = 10004;
	a[1440] = 10005;
	a[4990] = 10006;
	a[6900] = 10007;
	a[6930] = 10008;
	a[8999] = 10009;
	a[9999] = 10010;
	//先展示一下最初始的前10个数
	for (int i = 0;i < k;i++) {
		printf("%d ", a[i]);
	}
	printf("\n");
	//再展示筛选出来的前10个数
	PrintTopK(a, n, k);
}
int main() {
	TeatTopK();
}

测试结果:
由于不对前10个最大的数有顺序要求,因此每次运行完程序得到的前10个数的顺序不一样。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

IO / day01 作业。

1.使用fgets统计一个文件的行号 //使用fgets统计一个文件的行号#include <string.h> #include <stdlib.h> #include <stdio.h>int main(int argc, const char *argv[]) {if(argc<2) //获取文件名{printf("input error\n!");printf("usage…

Flutter页面刷新失败?看看是不是这个原因

文章目录 问题描述解决办法在控件A中定义回调函数在页面中使用控件A 原因分析回顾问题原因分析 setState使用注意事项上下文正确性异步更新避免深层嵌套避免频繁调用避免在 build 方法中调用避免在 dispose 方法中调用 问题描述 我用flutter开发了一个页面&#xff0c;页面上有…

苍穹外卖——删除购物车信息

1. 删除购物车中一个商品 1.1 产品原型 1.2 接口设计 1.3 数据模型 shopping_cart表&#xff1a; -- auto-generated definition create table shopping_cart (id bigint auto_increment comment 主键primary key,name varchar(32) null comment 商品名称…

上门服务系统|东郊到家软件提供高效服务的科技支柱

预约上门服务系统的崛起改变了传统服务行业的格局。用户不再需要亲自前往实体店面&#xff0c;而是通过几次点击就能享受到各类服务。这背后离不开预约上门服务系统的智能化和高效性&#xff0c;而源码正是这个系统的灵魂所在。下面小编就给大家介绍下上门服务系统开发优势。 1…

windows 如何卸载证书

1、windows r 2、输入 certmgr.msc 3、进入证书管理&#xff0c;选择个人 4、选择个人---找到要删除的证书&#xff0c;删除 就可以了。

LiveGBS流媒体平台GB/T28181功能-概览中负载信息直播、回放、播放、录像、H265、级联查看负载会话列表

LiveGBS常见问题-概览中负载信息具体表示什么直播、回放、播放、录像、H265、级联等 1、负载信息2、负载信息说明3、会话列表查看3.1、会话列表 4、搭建GB28181视频直播平台 1、负载信息 实时展示直播、回放、播放、录像、H265、级联等使用数目 2、负载信息说明 直播&#x…

SD-WAN组网中的CPE及云服务CPE部署方法

什么是CPE&#xff1f; CPE全称为Customer Premises Equipment&#xff0c;即客户端设备&#xff0c;在SD-WAN中通常为路由器&#xff0c;部署在中心点和分支上&#xff0c;提供连接和路由、协议转换、流量监控等功能。一般可分为硬件CPE和虚拟化CPE&#xff08;virtual CPE&a…

项目设计---网页五子棋

文章目录 一. 项目描述二. 核心技术三. 需求分析概要设计四. 详细设计4.1 实现用户模块4.1.1 约定前后端交互接口4.1.2 实现数据库设计4.1.3 客户端页面展示4.1.4 服务器功能实现 4.2 实现匹配模块4.2.1 约定前后端交互接口4.2.2 客户端页面展示4.2.3 服务器功能实现 4.3 实现对…

带你用uniapp从零开发一个仿小米商场_10.开发一个占剩余窗口的滚动区域

首先是一个头部的tag切换栏,这个很简单,就不多说 源码奉上 <scroll-view scroll-x class"border scroll-row" style"height: 80rpx;"><view class"scroll-row-item" style"height: 80rpx;line-height: 80rpx;" v-for"(…

首批量子计算机即将部署!欧盟为波兰提供新算力优势

&#xff08;图片来源&#xff1a;网络&#xff09; 英国量子计算机开发商ORCA公司将为波兰的波兹南超级计算和网络中心&#xff08;PSNC&#xff09;提供两个PT-1光量子系统&#xff0c;以加速其在量子计算领域的研究和应用工作&#xff0c;如生物学、化学和机器学习领域。 …

目标检测——Mask R-CNN算法解读

论文&#xff1a;Mask R-CNN 作者&#xff1a;Kaiming He Georgia Gkioxari Piotr Dollar Ross Girshick 链接&#xff1a;https://arxiv.org/abs/1703.06870 代码&#xff1a;https://github.com/facebookresearch/Detectron R-CNN系列其他文章&#xff1a; R-CNN算法解读SPP…

WordPress(安装比子主题文件)zibll-7.5.1

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、新建网站二、配置ssl三.配置伪静态四.上传文件五.添加本地访问前言 提示:这里可以添加本文要记录的大概内容: 首先,我们要先理解什么是授权原理。 原理就是我们大家运营网站,点击授权…

【高效开发工具系列】Hutool DateUtil工具类

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Java核心知识点整理大全25-笔记

目录 25. Hadoop 25.1.1. 概念 25.1.2. HDFS 25.1.2.1. Client 25.1.2.2. NameNode 25.1.2.3. Secondary NameNode 25.1.2.4. DataNode 25.1.3. MapReduce 25.1.3.1. Client 25.1.3.2. JobTracker 25.1.3.3. TaskTracker 25.1.3.4. Task 25.1.3.5. Reduce Task 执行…

【代码】两阶段鲁棒优化/微电网经济调度入门到编程

内容包括 matlab-yalmipcplex微电网两阶段鲁棒经济调度&#xff08;刘&#xff09; matlab-yalmipcplex两阶段鲁棒微电网容量经济优化调度 两阶段鲁棒优化CCG列于约束生成和Benders代码&#xff0c;可扩展改编&#xff0c;复现自原外文论文 【赠送】虚拟储能单元电动汽车建…

FL Studio(水果软件)2024最新中文版云盘下载

如今&#xff0c;越来越多的音乐人选择使用音乐制作软件来进行音乐的创作&#xff0c;一台电脑、一款软件以及一个外接MIDI就是一个小型的音乐工作站。FL Studio成了音乐界萌新的首选&#xff0c;目前最新的版本为FL Studio2024版本。 你可以不知道如何做音乐&#xff0c;但是…

《opencv实用探索·七》一文看懂图像卷积运算

1、图像卷积使用场景 图像卷积是图像处理中的一种常用的算法&#xff0c;它是一种基本的滤波技术&#xff0c;通过卷积核&#xff08;也称为滤波器&#xff09;对图像进行操作&#xff0c;使用场景如下&#xff1a; 模糊&#xff08;Blur&#xff09;&#xff1a; 使用加权平…

你好!插值查找【JAVA】

1.初次相识 插值查找&#xff08;interpolation search&#xff09;是一种根据待查找关键字在有序数组中的大致位置决定查找范围的查找算法。插值查找与二分查找类似&#xff0c;区别在于插值查找对于待查找关键字在数组中的位置进行估计&#xff0c;从而更精准地定位到待查找关…

信息化系列——企业信息化建设

​在信息化浪潮的汹涌推进下&#xff0c;众多企业纷纷开启信息化建设之旅&#xff0c;并取得了引人注目的成果。然而&#xff0c;从整体上观览&#xff0c;我国企业的信息化水平虽已在逐步提升&#xff0c;但多数企业在信息化建设方面仍旧存在显著的不足。显然&#xff0c;信息…