排序【数据结构】

news2025/3/10 15:26:40

1、排序的概念

  • 排序: 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
  • 稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[ i ] = r[ j ],且 r[ i ] 在 r[ j ] 之前,而在排序后的序列中,r[ i ] 仍在 r[ j ] 之前,则称这种排序算法是稳定的;否则称为不稳定的。
  • 内部排序: 数据元素全部放在内存中的排序。
  • 外部排序: 数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

2、常见的排序算法

在这里插入图片描述

【1】直接插入排序

  • 直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

在这里插入图片描述

  • 实际中我们玩扑克牌时,就用了插入排序的思想
    在这里插入图片描述
  • 当插入第 i(i>=1) 个元素时,前面的 arr[0],arr[1],…,arr[i-1] 已经排好序,此时用 arr[i] 的排序码与 arr[i-1],arr[i-2],… 的排序码顺序进行比较,找到插入位置即将 arr[i] 插入,原来位置上的元素顺序后移。
  • 直接插入排序的特性总结:
    1、元素集合越接近有序,直接插入排序算法的时间效率越高
    2、时间复杂度:O(N^2)
    3、空间复杂度:O(1),它是一种稳定的排序算法
    4、稳定性:稳定
// 时间复杂度(最好):O(N) -- 顺序有序
// 时间复杂度(最坏):O(N^2) -- 逆序

void InsertSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		//[0, end] 有序,插入tmp依旧有序
		int end = i - 1;
		int tmp = a[i];

		while (end >= 0)
		{
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

在这里插入图片描述


【2】希尔排序

  • 希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离相同的记录分在同一组内,并对每一组内的记录进行排序。然后重复上述分组和排序的工作。当到 gap=1 时,所有记录在同一组内排好序。
    在这里插入图片描述
  • 希尔排序的特性总结:
    1、希尔排序是对直接插入排序的优化。
    2、当 gap > 1时都是预排序,目的是让数组更接近于有序。当 gap == 1时,数组已经接近有序的了,这样再排一次就会很快排出结果。这样整体而言,可以达到优化的效果。
    3、希尔排序的时间复杂度不好计算,因为 gap 的取值方法很多,导致很难去计算,因此在好些书中给出的希尔排序的时间复杂度都不固定。估计【O(N^1.3)】
    4、稳定性:不稳定
void ShellSort(int* a, int n)
{
	// 1、gap > 1 预排序
	// 2、gap == 1 直接插入排序

	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1; //+1可以保证最后一次一定是1
		//gap = gap / 2;

		//多组并排
		for (int i = 0; i < n - gap; ++i)
		{
			int end = i;
			int tmp = a[end + gap]; //提前记录tmp值
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


【3】选择排序

  • 选择排序基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。【此处对选择排序进行了优化,每轮同时选出最小和最大的数分别放在开头和末尾】

在这里插入图片描述

  • 直接选择排序的特性总结:
    1、直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
    2、时间复杂度:O(N^2)
    3、空间复杂度:O(1)
    4、稳定性:不稳定
void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	
	while(begin < end)
	{
		int maxi = 0;
		int mini = 0;

		for (int i = begin; i <= end; i++)
		{
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
			if (a[i] < a[mini])
			{
				mini = i;
			}
		}
		Swap(&a[begin], &a[mini]);

		//如果maxi和begin重叠,修正一下即可
		if (begin == maxi)
		{
			maxi = mini;
		}

		Swap(&a[end], &a[maxi]);

		begin++;
		end--;
	}
}

在这里插入图片描述


【4】堆排序

  • 堆排序 (Heapsort) 是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
    在这里插入图片描述
  • 堆排序的特性总结:
    1、堆排序使用堆来选数,效率就高了很多。
    2、时间复杂度:O(N*logN)
    3、空间复杂度:O(1)
    4、稳定性:不稳定
void AdjustDown(int* a, int n, int parent)
{
	int child = parent * 2 + 1;

	while (child < n)
	{
		//找出大孩子
		if (child + 1 < n && a[child] < a[child + 1])
		{
			child = child + 1;
		}

		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--;
	}
}

【5】冒泡排序

  • 冒泡排序基本思想:就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,冒泡排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

在这里插入图片描述

  • 冒泡排序的特性总结:
    1、冒泡排序是一种非常容易理解的排序
    2、时间复杂度:O(N^2)
    3、空间复杂度:O(1)
    4、稳定性:稳定
void BubbleSort(int* a, int n)
{
	//冒泡排序的趟数
	for (int i = 0; i < n-1; i++) //趟数:元素个数-1
	{
		bool flag = false;

		//一趟排序的过程
		for (int j = 0; j < n - i - 1; j++) //每趟的元素之间互相比较次数:元素个数-1-第几趟
		{
			if (a[j] > a[j + 1])
			{
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;

				flag = true;
			}
		}
		if (flag == false) //数组已经有序
		{
			break;
		}
	}
}

【6】快速排序

  • 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
  • 快速排序的特性总结:
    1、快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
    2、时间复杂度:最好:O(N*logN),最差O(N^2)
    3、空间复杂度:O(logN)
    4、稳定性:不稳定

(1)hoare版本

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

//方法一:hoare版本
int PartSort1(int* a, int left, int right)
{
	//加三数取中进行优化
	int mid = GetMidIndex(a, left, right);
	Swap(&a[left], &a[mid]);
	
	int keyi = left;
	while (left < right)
	{
		//右边找小
		while (left < right && a[right] >= a[keyi])
		{
			right--;
		}
		//左边找大
		while (left < right && a[left] <= a[keyi])
		{
			left++;
		}
		Swap(&a[left], &a[right]);
	}
	Swap(&a[keyi], &a[left]);
	return left;
}

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
	{
		return;
	}

	int keyi = PartSort1(a, begin, end);
	//[begin, keyi-1] keyi [keyi+1, end]

	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

(2)挖坑法

在这里插入图片描述

在这里插入图片描述

//方法二:挖坑法
int PartSort2(int* a, int left, int right)
{
	//加三数取中进行优化
	int mid = GetMidIndex(a, left, right);
	Swap(&a[left], &a[mid]);
	
	int key = a[left];
	int hole = left;
	while (left < right)
	{
		//右边找小
		while (left < right && a[right] >= key)
		{
			right--;
		}
		a[hole] = a[right];
		hole = right;

		//左边找大
		while (left < right && a[left] <= key)
		{
			left++;
		}
		a[hole] = a[left];
		hole = left;
	}
	a[hole] = key;
	return hole;
}

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
	{
		return;
	}

	int keyi = PartSort2(a, begin, end);
	//[begin, keyi-1] keyi [keyi+1, end]

	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

(3)前后指针版本

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

//方法三:前后指针法
//[left, right]
int PartSort3(int* a, int left, int right)
{
	//加三数取中进行优化
	int mid = GetMidIndex(a, left, right);
	Swap(&a[left], &a[mid]);
	
	int prev = left;
	int cur = left + 1;
	int keyi = left;

	while (cur <= right)
	{
		if (a[cur] < a[keyi] && ++prev != cur) //++prev != cur避免了在prev+1后和cur指向相同位置时的交换
		{
			Swap(&a[cur], &a[prev]);
		}
		cur++;
	}
	Swap(&a[prev], &a[keyi]);
	keyi = prev;
	return keyi;
}

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
	{
		return;
	}

	int keyi = PartSort3(a, begin, end);
	//[begin, keyi-1] keyi [keyi+1, end]

	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

(4)快排优化(三数取中、三路划分)

  • 快速排序的特性总结:
    1、快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
    2、时间复杂度:最好:O(N*logN),最差O(N^2)
    3、空间复杂度:O(logN)
    4、稳定性:不稳定

在这里插入图片描述

  • 优化:增加三数取中
//三数取中
int GetMidIndex(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return right;
		}
		else
		{
			return left;
		}
	}
	else
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return right;
		}
		else
		{
			return left;
		}
	}
}
  • 优化:三路划分【排序数组OJ】

在这里插入图片描述

void Swap(int* p, int* q)
{
	int tmp = *p;
	*p = *q;
	*q = tmp;
}

//三数取中【随机数取中】
int GetMidIndex(int* a, int left, int right)
{
	//int mid = (left + right) / 2;
	int mid = left + (rand() % (right - left)); //模到范围以内,以免加随机值越界

	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return right;
		}
		else
		{
			return left;
		}
	}
	else
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return right;
		}
		else
		{
			return left;
		}
	}
}

//三路划分
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
	{
		return;
	}

	int left = begin;
	int right = end;
	int cur = left + 1;

	//加三数取中进行优化
	int mid = GetMidIndex(a, left, right);
	Swap(&a[left], &a[mid]);

	int key = a[left];

	while (cur <= right)
	{
		if (a[cur] < key)
		{
			Swap(&a[left], &a[cur]);
			left++; //指向交换后的原a[left]值即还指向key
			cur++;
		}
		else if (a[cur] > key)
		{
			Swap(&a[cur], &a[right]);
			right--;
		}
		else
		{
			cur++;
		}
	}

	//小  l  r  大
	//[begin,left-1] [left,right] [right+1,end]

	QuickSort(a, begin, left - 1);
	QuickSort(a, right + 1, end);
}

int* sortArray(int* nums, int numsSize, int* returnSize){
	srand(time(0)); //随机数取中

	QuickSort(nums,0,numsSize-1);

	*returnSize = numsSize;
	return nums;
}

(5)非递归版本(用栈实现)

在这里插入图片描述

//非递归实现快排
void QuickSortNonR(int* a, int begin, int end)
{
	ST st;
	STInit(&st);
	STPush(&st, end); //先入后出
	STPush(&st, begin); //后进先出

	while (!STEmpty(&st))
	{
		int left = STTop(&st); //后进先出
		STPop(&st);

		int right = STTop(&st); //先入后出
		STPop(&st);

		int keyi = PartSort3(a, left, right);
		//[left, keyi-1] keyi [keyi+1, right]

		if (keyi + 1 < right)
		{
			STPush(&st, right);
			STPush(&st, keyi + 1);
		}

		if (left < keyi - 1)
		{
			STPush(&st, keyi - 1);
			STPush(&st, left);
		}
	}
	STDestroy(&st);
}

【7】归并排序

(1)递归版本

  • 基本思想:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
  • 归并排序核心步骤:
    在这里插入图片描述

在这里插入图片描述

  • 归并排序的特性总结:
    1、归并的缺点是需要O(N)的空间复杂度,归并排序的思想更多的是解决在磁盘中的外排序问题。
    2、时间复杂度:O(N*logN)
    3、空间复杂度:O(N)
    4、稳定性:稳定

在这里插入图片描述

在这里插入图片描述

//归并排序
void _MergeSort(int* a, int begin, int end, int* tmp)
{
	if (begin >= end)
	{
		return;
	}

	int mid = (begin + end) / 2;
	//[begin,mid] [mid+1,end]

	_MergeSort(a, begin, mid, tmp);
	_MergeSort(a, mid + 1, end, tmp);

	//归并两个区间
	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
		{
			tmp[i++] = a[begin1++];
		}
		else
		{
			tmp[i++] = a[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		tmp[i++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[i++] = a[begin2++];
	}
	memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1)); //计算区间个数左闭右闭要+1
}

void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);

	_MergeSort(a, 0, n - 1, tmp);

	free(tmp);
}

(2)非递归版本

在这里插入图片描述

在这里插入图片描述

//非递归实现归并排序 —— 归并一组,拷贝一组
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	
	//1  2  4...
	int gap = 1; //每组数据个数

	while (gap < n)
	{
		int j = 0;
		for (int i = 0; i < n; i += 2 * gap)
		{
			//每组的数据合并
			int begin1 = i, end1 = i + gap - 1; //计算右区间下标:左区间+间隔个数-1
			int begin2 = i + gap, end2 = i + 2 * gap - 1;

			//printf("[%d,%d][%d,%d]\n", begin1, end1, begin2, end2);

			if (end1 >= n || begin2 >= n)
			{
				break;
			}

			//修正
			if (end2 >= n)
			{
				end2 = n - 1;
			}

			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] <= a[begin2])
				{
					tmp[j++] = a[begin1++];
				}
				else
				{
					tmp[j++] = a[begin2++];
				}
			}

			while (begin1 <= end1)
			{
				tmp[j++] = a[begin1++];
			}

			while (begin2 <= end2)
			{
				tmp[j++] = a[begin2++];
			}

			//归并一组,拷贝一组
			memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1));
		}
		//printf("\n");
		gap *= 2;
	}
	free(tmp);
}
//非递归实现归并排序 —— 整体拷贝
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);

	// 1  2  4 ....
	int gap = 1;
	while (gap < n)
	{
		int j = 0;
		for (int i = 0; i < n; i += 2 * gap)
		{
			// 每组的合并数据
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;

			printf("修正前:[%d,%d][%d,%d]\n", begin1, end1, begin2, end2);

			//修正
			if (end1 >= n)
			{
				end1 = n - 1;

				// 不存在区间
				begin2 = n;
				end2 = n - 1;
			}
			else if (begin2 >= n)
			{
				// 不存在区间
				begin2 = n;
				end2 = n - 1;
			}
			else if(end2 >= n)
			{
				end2 = n - 1;
			}

			printf("修正后:[%d,%d][%d,%d]\n", begin1, end1, begin2, end2);

			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] <= a[begin2])
				{
					tmp[j++] = a[begin1++];
				}
				else
				{
					tmp[j++] = a[begin2++];
				}
			}

			while (begin1 <= end1)
			{
				tmp[j++] = a[begin1++];
			}

			while (begin2 <= end2)
			{
				tmp[j++] = a[begin2++];
			}
		}
		printf("\n");
		memcpy(a, tmp, sizeof(int) * n);
		gap *= 2;
	}
	free(tmp);
}

(3)递归版本优化(小区间优化)

在这里插入图片描述

void _MergeSort(int* a, int begin, int end, int* tmp)
{
	if (begin >= end)
	{
		return;
	}

	//小区间优化
	if (end - begin + 1 < 10) //小于10,大概可以减少最后三层,即减少80%的调用
	{
		InsertSort(a + begin, end - begin + 1);
		return;
	}

	int mid = (begin + end) / 2;
	//[begin,mid] [mid+1,end]

	_MergeSort(a, begin, mid, tmp);
	_MergeSort(a, mid + 1, end, tmp);

	//归并两个区间
	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] < a[begin2])
		{
			tmp[i++] = a[begin1++];
		}
		else
		{
			tmp[i++] = a[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		tmp[i++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[i++] = a[begin2++];
	}
	memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1)); //计算区间个数左闭右闭要+1
}

void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);

	_MergeSort(a, 0, n - 1, tmp);

	free(tmp);
}

【8】计数排序

  • 计数排序的特性总结:
    1、数排序在数据范围集中时,效率很高,但是适用范围及场景有限。
    2、时间复杂度:O(MAX(N,范围))
    3、空间复杂度:O(范围)
    4、稳定性:稳定
    5、缺陷1:依赖数据范围,适用于范围集中的数组
    6、缺陷2:只能用于整形

在这里插入图片描述

//计数排序
//时间复杂度:O(N+Range)
//空间复杂度:O(Range)
void CountSort(int* a, int n)
{
	int min = a[0], max = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] < min)
		{
			min = a[i];
		}
		if (a[i] > max)
		{
			max = a[i];
		}
	}
	int range = max - min + 1;
	int* countA = (int*)malloc(sizeof(int) * range);
	memset(countA, 0, sizeof(int) * range);

	//统计次数
	for (int i = 0; i < n; i++)
	{
		countA[a[i] - min]++; //相对映射
	}

	//排序
	int k = 0;
	for (int j = 0; j < range; j++)
	{
		while (countA[j]--)
		{
			a[k] = j + min;
			k++;
		}
	}
	free(countA);
	return;
}

3、内排序外排序

在这里插入图片描述

4、排序算法复杂度及稳定性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

一个月学通Python(十九):Cookie和Session是什么(Web开发)

专栏介绍 结合自身经验和内部资料总结的Python教程&#xff0c;每天3章&#xff0c;1个月就能全方位的完成Python的学习并进行实战开发&#xff0c;学完了定能成为大佬&#xff01;加油吧&#xff01;卷起来&#xff01; 全部文章请访问专栏&#xff1a;《Python全栈教程&…

C++:这门语言优势在哪?命名空间以及缺省参数?

文章目录 C的优势解决命名空间的问题 缺省参数 C的优势 C和C语言比起来有许多优势&#xff0c;这里我们先举一个例子&#xff0c;后续进行补充 解决命名空间的问题 首先看这样的代码&#xff1a; #include <stdlib.h> #include <stdio.h>int rand 0;int main(…

k8s服务发现之第二弹Service详解

创建 Service Kubernetes Servies 是一个 RESTFul 接口对象&#xff0c;可通过 yaml 文件创建。 例如&#xff0c;假设您有一组 Pod&#xff1a; 每个 Pod 都监听 9376 TCP 端口每个 Pod 都有标签 appMyApp apiVersion: v1 kind: Service metadata:name: my-service spec:s…

创建users子应用

1.创建&#xff1a;(venv) xxxx>python manage.py startapp users 2.移动到apps里面&#xff1b; 3.在settings里面注册子应用&#xff1b; # 注册子应用 apps/users apps/users/apps name apps.users 这个路径是什么就写什么 INSTALLED_APPS [ # 用[../namage.py st…

架构训练营学习笔记:4-3存储架构模式之分片架构和分区架构

分片架构的本质&#xff1a; 分片架构能提升写性能和存储性能&#xff0c;对应的主备架构的本质是备份&#xff0c;主从架构本质提升读性能。 分片架构的两个关键点&#xff1a;分片规则跟路由规则 分片规则&#xff1a; 选择基数比较大的某个数据键值&#xff0c;让数据均匀…

第七章 集成学习

文章目录 第七章 集成学习7.1个体和集成7.2Boosting和AdaBoost7.3Bagging和随机森林7.3.1Bagging7.3.2随机森林 7.4结合策略7.4.1平均法7.4.2投票法7.4.3学习法 7.6实验&#xff1a;Adaboost 第七章 集成学习 7.1个体和集成 集成学习通过构建并结合多个学习器来完成学习任务&…

TS报错Cannot find module ‘xxx‘ or its corresponding type declarations

最近使用 vite vue3 ts 开发一个文本标注的 web 平台&#xff0c;在项目中使用了一个 js-mark 的 npm 包&#xff0c;但是在 import 导入后出现了 TS 报错&#xff1a;TS2307: Cannot find module js-mark or its corresponding type declarations.、无法解析模块 js-mark 的…

Safe Policy Optimization 复现

复现结果 在 PointGoal1、CarGoal1、Velocity-Walker2d 三个任务上测试了 RCPO&#xff0c;CRPO 以及 Safe-Policy-Optimization 中实现的 CPO&#xff0c;PPO-Lag 算法。 CarGoal PointGoal PointGoal1 和 CarGoal1 任务相对比较困难&#xff0c;在探索初期就很容易违反约束…

Dart语言(01)环境安装基础语法总结

0 说明&#xff1a; 说明&#xff1a;该系列教程主要是为有一定语言基础 C/C的程序员&#xff0c;快速学习一门新语言所采用的方法&#xff0c;属于在C/C基础上扩展新语言只是体系的方式。 1 Dart语言简介 Dart亮相于2011年10月10日至12日在丹麦奥尔胡斯举行的GOTO大会&…

【动手学深度学习】--09.PyTorch神经网络基础

文章目录 PyTorch神经网络基础1.层和块1.1自定义块1.2顺序块1.3在前向传播函数中执行代码 2.参数管理2.1参数访问2.1.1目标参数2.1.2一次性访问所有参数2.1.3从嵌套块收集参数 2.2参数初始化2.2.1内置初始化2.2.2自定义初始化 2.3参数绑定 3.自定义层3.1不带参数的层3.2带参数的…

Python爬虫学习笔记:1688商品详情API 开发API接口文档

1688API接口是阿里巴巴集团推出的一种开放平台&#xff0c;提供了丰富的数据接口、转换工具以及开发资源&#xff0c;为开发者提供了通用的应用接口及大量数据资源&#xff0c;支持开发者在1688上进行商品搜索、订单管理、交易报表及物流等方面的操作。 1688API接口主要包含以…

解密成功之道!加湿制冷设备企业如何借助CRM系统降低经营成本?

如何降低企业经营成本的同时提高效率是加湿制冷设备企业关注的重要问题。在这篇软文中&#xff0c;我们将探讨如何通过CRM系统来实现这一目标。企业可以借助CRM系统提高客户关系管理水平&#xff0c;优化销售流程&#xff0c;提升售后服务&#xff0c;从而降低成本&#xff0c;…

价格监测的作用有哪些

随着品牌的发展&#xff0c;销售渠道也会逐步增多&#xff0c;渠道中的问题也会逐渐显现&#xff0c;比如低价、乱价、窜货、假货&#xff0c;所以品牌一般都会进行控价治理&#xff0c;控价最重要的一步便是价格监测&#xff0c;监测出来的价格高低&#xff0c;能直接反应渠道…

抑郁症缓解方法:从心理到行为,全方位提升生活质量

抑郁症是一种常见的心理疾病&#xff0c;不仅仅是心情低落&#xff0c;它还伴随着一系列的身体和心理症状。在应对抑郁症时&#xff0c;除了积极寻求医学专业人士的帮助之外&#xff0c;以下这些招数也可以帮助你缓解抑郁症。 1.保持规律的生活习惯&#xff1a;抑郁症患者往往会…

小程序地图个性化样式组件要收费了!

地图个性化样式组件 自2023年6月29日0点起&#xff0c;该能力需要先购买再使用。若未购买&#xff0c;届时将无法使用该能力。具体购买方式见付费管理。自2023年6月29日0时起&#xff0c;个性化地图配置界面的入口统一为微信公众平台-付费管理&#xff0c;请从此入口进入&#…

STUN/TURN/ICE

RFC 5389 - Session Traversal Utilities for NAT (STUN) https://www.cnblogs.com/pannengzhi/p/5041546.html https://www.cnblogs.com/pannengzhi/p/5048965.html STUN : Session Traversal Utilities for NAT, 一个协助穿越NAT的工具&#xff0c;运行在UDP和TCP之上。 NA…

yolov5(v7.0)网络修改实践一:集成YOLOX的backbone(CSPDarknet和Pafpn)到yolov5(v7.0)框架中

yolov5太好用了&#xff0c;无论是实际做工程还是学习研究&#xff0c;yolov5都比较好上手&#xff0c;而且现在工业界yolov5也应用广泛。但是&#xff0c;作为学习研究&#xff0c;有不少在yolov5之后提出的涨点算法&#xff0c;还是有价值进行研究的&#xff0c;也便于跟进当…

高效管理物流:利用批量查询申通物流信息的技巧

随着电子商务的飞速发展&#xff0c;快递已经成为了现代人生活中不可或缺的一部分。作为国内一家领先的快递公司&#xff0c;申通快递服务广泛&#xff0c;覆盖全国各地。在使用申通快递服务时&#xff0c;我们通过申通快递单号可以方便地查询物流信息。然而&#xff0c;许多人…

python开发项目基于语音识别的智能垃圾分类系统的设计与实现

博主介绍&#xff1a;擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例…

Ae 效果:CC Mr. Smoothie

风格化/CC Mr. Smoothie Stylize/CC Mr. Smoothie CC Mr. Smoothie&#xff08;平滑先生&#xff09;效果可以从一个图层上的两个点进行颜色采样&#xff0c;并将这个两点之间的颜色重映射到另一个图层上&#xff0c;可通过控制重映射的平滑度从而创建迷幻的外观效果。 ◆ ◆ …