详解—数据结构—<常用排序>基本实现和代码分析

news2024/9/28 19:20:16

目录

一.排序的概念及其运用

1.1排序的概念

1.2排序运用​编辑

1.3 常见的排序算法​编辑

二.常见排序算法的实现

2.1 插入排序

2.1.1基本思想:

2.1.2直接插入排序:

2.1.3 希尔排序( 缩小增量排序 )

2.2 选择排序

2.2.1基本思想:

2.2.2 直接选择排序:

2.2.3 堆排序

2.3 交换排序

2.3.1冒泡排序​编辑

2.3.2 快速排序

2.3.2.1. hoare版本

2.3.2.2. 挖坑法

2.3.2.3. 前后指针版本

2.3.2.4. 非递归版本

2.3.3 快速排序优化

2.3.3.1. 三数取中法选key

2.3.3.2. 递归到小的子区间时,可以考虑使用插入排序

2.4 归并排序

2.5 非比较排序

三.排序算法复杂度及稳定性分析​编辑


一.排序的概念及其运用


1.1排序的概念

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

1.2排序运用

1.3 常见的排序算法

912. 排序数组 - 力扣(LeetCode)力扣的排序OJ 题可以用各种排序跑这个OJ

二.常见排序算法的实现

2.1 插入排序

2.1.1基本思想:

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

实际中我们玩扑克牌时,就用了插入排序的思想

2.1.2直接插入排序:

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

void InsertSort(int a[], int n)
{
	//i 每一个数都算是插入进去的
	for (int i = 0;i < n - 1;i++)
	{
		//end 数组内数据个数
		int end = i; 
		//tmp 为插入数据
		int tmp = a[end + 1];

		//插入数据与数组内数据比较,如果插入数据比数组最后一个数据大 好 直接原地插入 
		//跳出循环 ,否则,跟数组内数据比较 找到数组内合适的位置插入
		while (end>=0) // 数组内数据遍历到a【0】
		{
			if (tmp < a[end]) //插入数据 与 数组最后位置比较
			{
				a[end + 1] = a[end];  // 小于 往前走 
				--end;
			}
			else
			{  
				break;    //大于 结束
			}
			a[end + 1] = tmp; //
		}
		
	}
}

直接插入排序的特性总结:

1. 元素集合越接近有序,直接插入排序算法的时间效率越高
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1),它是一种稳定的排序算法
4. 稳定性:稳定

2.1.3 希尔排序( 缩小增量排序 )

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序

void ShellSort(int* a, int n)
{
	//希尔排序
	 
	//1. 先预排序
	// 预排序 就是  把要排序数组分成 gap组 然后开始比较 交换
	// 
	//2.在插入排序

	// gap > 1 预排序
	// gap == 1 直接插入排序
	int gap = n;
	while (gap > 1) //
	{
		// gap = gap / 2; 
		gap = gap / 3 + 1;// 如果不加1  就有可能到不了 1 

		//当 gap  =1 时就是直插  ,gap 越小 与排序越接近排序好的状态
		for (int i = 0; i < n - gap; ++i)
		{
			int end = i;
			int tmp = a[end + gap]; 

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

			a[end + gap] = tmp;
		}
	}
}

希尔排序的特性总结:

1. 希尔排序是对直接插入排序的优化。
2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
3. 希尔排序的时间复杂度不好计算,需要进行推导,推导出来平均时间复杂度: O(N^1.3—N^2)
4. 稳定性:不稳定

2.2 选择排序

2.2.1基本思想:

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

2.2.2 直接选择排序:

在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素


若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换


在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

void SelectSort(int* a, int n)
{
	int begin = 0, end = n - 1;

	while (begin < end)
	{
		int mini = begin, maxi = begin;

		for (int i = begin + 1; i <= end; ++i)
		{
			if (a[i] < a[mini])//遍历数组 找最小数据
			{
				mini = i;
			}

			if (a[i] > a[maxi])//找最大数据
			{
				maxi = i;
			}
		}

		Swap(&a[begin], &a[mini]); //交换最开始和 最小的数据
		if (maxi == begin)    //如果最大的是最开始的数据,上面交换最大的数据被换到了最小的数据位置上
			maxi = mini;      //把最小数据的位置交给最大数据

		Swap(&a[end], &a[maxi]);//交换最后和 最大的数据
		++begin;
		--end;
	}
}

直接选择排序的特性总结:

1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

2.2.3 堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆

//向下调整建堆
void AdjustDown(int* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		// 确认child指向大的那个孩子
		if (child + 1 < n && a[child + 1] > a[child])
		{
			++child;
		}

		// 1、孩子大于父亲,交换,继续向下调整
		// 2、孩子小于父亲,则调整结束
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
//堆排
void HeapSort(int* 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;
	}
}

堆排序的特性总结:

1. 堆排序使用堆来选数,效率就高了很多。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

2.3 交换排序

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

2.3.1冒泡排序

void BubbleSort(int* a, int n)
{
	int i = 0;
	for (i = 0;i < n - 1;i++)
	{
		int j = 0;
		for (j = 0;j < n - i - 1;j++)
		{
			if (a[j] > a[j + 1])
			{
				int tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
			}
		}
	}
}

冒泡排序的特性总结:

1. 冒泡排序是一种非常容易理解的排序
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1)
4. 稳定性:稳定

2.3.2 快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

将区间按照基准值划分为左右两半部分的常见方式有:

1. hoare版本
2. 挖坑法
3. 前后指针版本

4.非递归版本

2.3.2.1. hoare版本

1、选出一个key,一般是最左边或是最右边的。
2、定义一个begin和一个end,begin从左向右走,end从右向左走。(需要注意的是:若选择最左边的数据作为key,则需要end先走;若选择最右边的数据作为key,则需要bengin先走)。
3、在走的过程中,若end遇到小于key的数,则停下,begin开始走,直到begin遇到一个大于key的数时,将begin和right的内容交换,end再次开始走,如此进行下去,直到begin和end最终相遇,此时将相遇点的内容与key交换即可。(选取最左边的值作为key)
4.此时key的左边都是小于key的数,key的右边都是大于key的数
5.将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作,此时此部分已有序

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
	{
		return;
	}
	int left = begin, right = end;
	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[left], &a[keyi]);
	keyi = left;

	// [begin, keyi-1]  keyi [keyi+1, end]
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}
2.3.2.2. 挖坑法

挖坑法思路与hoare版本(左右指针法)思路类似
1.选出一个数据(一般是最左边或是最右边的)存放在key变量中,在该数据位置形成一个坑


2、还是定义一个L和一个R,L从左向右走,R从右向左走。(若在最左边挖坑,则需要R先走;若在最右边挖坑,则需要L先走)

后面的思路与hoare版本思路类似在此处就不说了

//快速排序法  挖坑法
void QuickSort1(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	int left = begin,right = end;
	int key = arr[begin];
	while (begin < end)
	{
		//找小
		while (arr[end] >= key && begin < end)
		{
			--end;
		}
		//小的放到左边的坑里
		arr[begin] = arr[end];
		//找大
		while (arr[begin] <= key && begin < end)
		{
			++begin;
		}
		//大的放到右边的坑里
		arr[end] = arr[begin];
	}
	arr[begin] = key;
	int keyi = begin;
	//[left,keyi-1]keyi[keyi+1,right]
	QuickSort1(arr, left, keyi - 1);
	QuickSort1(arr, keyi + 1, right);
}
2.3.2.3. 前后指针版本

1、选出一个key,一般是最左边或是最右边的。


2、起始时,prev指针指向序列开头,cur指针指向prev+1。


3、若cur指向的内容小于key,则prev先向后移动一位,然后交换prev和cur指针指向的内容,然后cur指针++;若cur指向的内容大于key,则cur指针直接++。如此进行下去,直到cur到达end位置,此时将key和++prev指针指向的内容交换即可。

经过一次单趟排序,最终也能使得key左边的数据全部都小于key,key右边的数据全部都大于key。

然后也还是将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作

//快速排序法  前后指针版本
void QuickSort2(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	int cur = begin, prev = begin - 1;
	int keyi = end;
	while (cur != keyi)
	{
		if (arr[cur] < arr[keyi] && ++prev != cur)
		{
			swap(&arr[cur], &arr[prev]);
		}
		++cur;
	}
	swap(&arr[++prev],&arr[keyi]);
	keyi = prev;
	//[begin,keyi -1]keyi[keyi+1,end]
	QuickSort2(arr, begin, keyi - 1);
	QuickSort2(arr, keyi + 1, end);

}
2.3.2.4. 非递归版本
void QuickSortNonR(int* a, int begin, int end)
{
	Stack st;
	StackInit(&st);
	StackPush(&st, begin);
	StackPush(&st, end);

	while (!StackEmpty(&st))
	{
		int right = StackTop(&st);
		StackPop(&st);
		int left = StackTop(&st);
		StackPop(&st);

		int keyi = left;
		int prev = left, cur = right + 1;
		while (cur <= end)
		{
			// 找到比key小的值时,跟++prev位置交换,小的往前翻,大的往后翻
			if (a[cur] < a[keyi] && ++prev != cur)
				Swap(&a[prev], &a[cur]);

			++cur;
		}

		Swap(&a[prev], &a[keyi]);
		keyi = prev;

		// [left, keyi-1] keyi [keyi+1, right]
		if (keyi + 1 < right)
		{
			StackPush(&st, keyi + 1);
			StackPush(&st, right);
		}

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

	StackDestroy(&st);
}

2.3.3 快速排序优化

2.3.3.1. 三数取中法选key
int Fetchmid(int* a, int begin, int end)
{
	int mid = (begin + end) / 2;
	if (a[begin] < a[mid])
	{
		if (a[mid] < a[end])
		{
			return mid;
		}
		else if (a[begin] > a[end])
		{
			return begin;
		}
		else
		{
			return end;
		}
	}
	else // a[begin] > a[mid]
	{
		if (a[mid] > a[end])
		{
			return mid;
		}
		else if (a[begin] < a[end])
		{
			return begin;
		}
		else
		{
			return end;
		}
	}
}
2.3.3.2. 递归到小的子区间时,可以考虑使用插入排序
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
	{
		return;
	}
	//小区间优化
	if (end - begin < 12)
	{
		//当小于12 个数的时候用直接插入法插入
		InsertSort(a+begin, end - begin);
	}
	else
	{
		int left = begin, right = end;
		int keyi = Fetchmid(a,begin, end);
		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[left], &a[keyi]);
		keyi = left;

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

快速排序的特性总结:

1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
2. 时间复杂度:O(N*logN)

3. 空间复杂度:O(logN)
4. 稳定性:不稳定

2.4 归并排序

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

// 归并排序递归实现
void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	_MergeSort(a,0,n-1,tmp);

	free(tmp);
	tmp = NULL;
}
// 归并排序非递归实现
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc");
		exit(-1);
	}

	// 归并每组数据个数,从1开始,因为1个认为是有序的,可以直接归并
	int rangeN = 1;
	while (rangeN < n)
	{
		for (int j = 0;j < n;j += 2 * rangeN)
		{
			int begin1 = j; int end1 = j+ rangeN -1;
			int begin2 = j+ rangeN, end2 = j + 2 * rangeN - 1;

			if (end1 > n)//end1越界  begin2 和 end2 肯定越界
			{
				break;
			}
			else if (begin2 > n)//begin2 越界  end2 肯定越界
			{
				break;
			}
			else if (end2 > n)
			{
				end2 = n - 1;
			}

			int i = j;
			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 + j, tmp + j, sizeof(int) * (end2 - j + 1));
		
		}
		rangeN *= 2;
	}

	free(tmp);
	tmp = NULL;
}

归并排序的特性总结:

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

2.5 非比较排序

计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。 操作步骤:

1. 统计相同元素出现次数
2. 根据统计的结果将序列回收到原来的序列中

void CountSort(int* arr, int size)
{
	int i;
	int minValue = arr[0];
	int maxValue = arr[0];
	int range = 0;
	int* tmp = 0;
	int count = 0;
	for (i = 0; i < size; i++)//计算数据的分散空间
	{
		if (arr[i] < minValue) {
			minValue = arr[i];
		}
		if (arr[i] > maxValue) {
			maxValue = arr[i];
		}
	}
	range = maxValue - minValue + 1;
	tmp = (int*)malloc(sizeof(arr[0]) * size);//申请辅助空间
	if (tmp == NULL)
		return;
	memset(tmp, 0, sizeof(int) * range);//初始化

	for (i = 0; i < size; i++)//统计每个元素出现的次数
	{
		tmp[arr[i] - minValue]++;
	}

	for (i = 0;i < range;i++)//通过统计tmp[];回收元素
	{
		while (tmp[i]--)
		{
			arr[count++] = i + minValue;
		}
	}
	free(tmp);
}

计数排序的特性总结:

1. 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限。
2. 时间复杂度:O(MAX(N,范围))
3. 空间复杂度:O(范围)
4. 稳定性:稳定

三.排序算法复杂度及稳定性分析

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

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

相关文章

大模型工具:LangChain 原理与实战案例

LangChain 是什么&#xff1f; LangChain是一个用于开发由语言模型驱动的应用程序的框架。它使得可以构建以下类型的应用程序&#xff1a; 数据感知&#xff1a;将语言模型与其他数据源连接起来 智能&#xff1a;允许语言模型与其环境进行交互 LangChain的主要价值在于&…

【JavaSE】Java进阶知识一(泛型详解,包括泛型方法,协变,逆变,擦除机制)

目录 泛型 1. 什么是泛型 2.泛型方法 3.通配符上界&#xff08;泛型的协变&#xff09; 4.通配符下界&#xff08;泛型的逆变&#xff09; 5.泛型的编译&#xff08;擦除机制&#xff09; 泛型 泛型&#xff1a;就是让一个类能适用于多个类型&#xff0c;就是在封装数据结…

前端---vscode 的基本使用

1. vscode 的基本介绍 全拼是 Visual Studio Code (简称 VS Code) 是由微软研发的一款免费、开源的跨平台代码编辑器&#xff0c;目前是前端(网页)开发使用最多的一款软件开发工具。 2. vscode 的安装 下载网址: Download Visual Studio Code - Mac, Linux, Windows选择对应…

PyQt5和Qt designer的详细安装教程

Qt designer界面和所有组件功能的详细介绍参考&#xff1a;https://blog.csdn.net/qq_43811536/article/details/135186862?spm1001.2014.3001.5501 目录 0. 写在前面1. Anaconda创建虚拟环境2. 安装PyQt5和Qt designer3. 测试安装成功 0. 写在前面 Qt Designer是Qt提供的一种…

Tiny Object Detection

文章目录 RFLA: Gaussian Receptive Field based Label Assignment for Tiny Object Detection&#xff08;ECCV2022&#xff09;Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection&#xff08;CVPR2023&#xff09;TOD-CMLNN&#xff08;2023&#xff09; …

RK3568平台开发系列讲解(Linux系统篇)Linux 热拔插机制 mdev的使能

🚀返回专栏总目录 文章目录 一、什么是热插拔二、热插拔的机制三、mdev的开启沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 Linux 热拔插。 一、什么是热插拔 热插拔是指在设备运行的情况下,能够安全地插入或拔出硬件设备,而无需关闭或重启系统。这意…

关于Nacos各日志以及解决Nacos中疯狂输出日志的问题

目录 前言1. 各日志内容2. 日志解析2.1 服务端日志2.2 客户端日志 前言 越来越发觉硬盘不够用&#xff0c;发现是运行了2年的Nacos中存了很多log日志&#xff0c;具体如下&#xff1a; 于是得了解下各个日志中的作用&#xff0c;防止不必要的输出占用硬盘空间&#xff01; …

Web前端-JavaScript(Dom高级)

文章目录 1.1 自定义属性操作1.1.1 获取属性值1.1.2 设置属性值1.1.3 移除属性值1.1.4 案例一 1.2 节点操作1.2.1 节点概述1.2.2 节点层级1.2.3 父级节点1.2.4 子节点1.2.5 兄弟节点1.2.6 创建节点1.2.7 添加节点1.2.8 删除节点1.2.9 案例二1.2.10 创建元素的三种方式(了解) 1.…

LabVIEW在横向辅助驾驶系统开发中的应用

LabVIEW在横向辅助驾驶系统开发中的应用 随着横向辅助驾驶技术的快速发展&#xff0c;越来越多的研究致力于提高该系统的效率和安全性。项目针对先进驾驶辅助系统&#xff08;ADAS&#xff09;中的横向辅助驾驶进行深入研究。在这项研究中&#xff0c;LabVIEW作为一个强大的系…

GEE数据集——USGS全球地震数据集

美国地质勘探局全球地震数据集 美国地质调查局地震灾害计划 (EHP) 提供全面的地震数据集&#xff0c;为全球监测、研究和地震防备提供宝贵资源。该数据集包含来自各种来源的地震信息&#xff0c;包括地震台、卫星图像和地面观测。持续更新&#xff0c;截至 2023 年 10 月 10 日…

mysql原理--连接查询的成本

1.准备工作 连接查询至少是要有两个表的&#xff0c;只有一个 single_table 表是不够的&#xff0c;所以为了故事的顺利发展&#xff0c;我们直接构造一个和 single_table 表一模一样的 single_table2 表。为了简便起见&#xff0c;我们把 single_table 表称为 s1 表&#xff0…

模糊测试:使用随机输入破坏事物

模糊测试&#xff1a;使用随机输入破坏事物 一个简单的模糊器模糊测试外部程序创建输入文件调用外部程序长时间运行的模糊测试 模糊测试器的发现缓冲区溢出缺少错误检查 我们将从最简单的测试生成技术之一开始&#xff0c;随机文本生成&#xff08;也称为模糊测试&#xff09;的…

Spring Cloud Gateway官方文档学习笔记

Spring Cloud Gateway官方文档学习笔记 前言 基础知识&#xff1a;API网关基础知识总结面试题&#xff1a;Spring Cloud Gateway夺命连环10问&#xff1f; 何为网关&#xff1f; 什么是网关&#xff1f;理解成火车站的检票口&#xff0c;统一 检票 网关优点&#xff1a; 统…

C#上位机与欧姆龙PLC的通信05---- HostLink协议

1、介绍 Hostlink协议是欧姆龙PLC与上位机链接的公开协议。上位机通过发送Hostlink命令&#xff0c;可以对PLC进行I/O读写、可以对PLC进行I/O读写、改变操作模式、强制置位/复位等操作。由于是公开协议&#xff0c;即便是非欧姆龙的上位设备&#xff08;软件&#xff09;&…

王者荣耀展示

..在写代码前要创建这些文件夹&#xff0c;并储存图片 代码 package com.sxt; import javax.swing.*; import java.awt.*; public class Background extends GameObject { public Background(GameFrame gameFrame) { super(gameFrame); // TODO Aut…

第5章 散列

我们在第4章讨论了查找树ADT&#xff0c;它允许对一组元素进行各种操作。本章讨论散列表(hash table)ADT&#xff0c;不过它只支持二叉查找树所允许的一部分操作。 散列表的实现常常叫作散列(hashing)。散列是一种以常数平均时间执行插入、删除和查找的技术。但是&#xff0c;那…

运维大模型探索之 Text2PromQL 问答机器人

作者&#xff1a;陈昆仪&#xff08;图杨&#xff09; 大家下午好&#xff0c;我是来自阿里云可观测团队的算法工程师陈昆仪。今天分享的主题是“和我交谈并获得您想要的PromQL”。今天我跟大家分享在将AIGC技术运用到可观测领域的探索。 今天分享主要包括5个部分&#xff1a;…

【Linux系统基础】(3)在Linux上部署运维监控Zabbix和Grafana

目录 运维监控Zabbix部署简介安装安装前准备 - Mysql安装Zabbix Server 和 Zabbix Agenta. 安装Zabbix yum库b. 安装Zabbix Server、前端、Agentc. 初始化Mysql数据库d. 为Zabbix Server配置数据库e. 配置Zabbix的PHP前端 配置zabbix 前端&#xff08;WEB UI&#xff09; 运维监…

学习在UE中通过Omniverse实现对USD文件的Live-Sync(实时同步编辑)

目标 前一篇 学习了Omniverse的一些基础概念。本篇在了解这些概念的基础上&#xff0c;我想体验下Omniverse的一些具体的能力&#xff0c;特别是 Live-Sync (实时同步) 相关的能力。 本篇实践了使用Omniverse的力量在UE中建立USD文件的 Live-Sync 编辑。由于相关的知识我是从…

将Go语言开发的Web程序部署到K8S

搭建K8S基础环境 如果已经有K8S环境的同学可以跳过&#xff0c;如果没有&#xff0c;推荐你看看我的《Ubuntu22加Minikue搭建K8S环境》&#xff0c;课程目录如下&#xff1a; Ubuntu22安装Vscode 下载&#xff1a;https://code.visualstudio.com/Download 安装命令&#…