文章目录
- 选择排序
 - 1.直接选择排序
 - 优化直接选择排序
 
- 2. 堆排序
 
 
 
选择排序
基本思想
 选组排序是从待排序数据中选出最大/最小的元素放入到序列的起始位置,直到待排序数据全部有序。
直接选择排序和堆排序的基本思想均符合选择排序。
1.直接选择排序
假设数据按升序排序
基本步骤
- 在待排序数据arr[i]-arr[n-1]中选出最小元素
 - 如果选出的min不处于待排数据第一个位置时,交换min与arr[i]
 - 重复上述操作直至待排序数据全部有序
 
下面动图演示直接选择排序

代码
void SelectSort(int* arr, int sz)
{
	int left = 0;
	while (left < sz - 1)
	{
		int minPos = left;//每次将待排序数组第一个元素设置为最小值
		//选出待排序数据中最小值
		for (int i = left; i < sz; i++)
		{
			if (arr[i] < arr[minPos])
			{
				minPos = i;
			}
		}
		//交换最小值和arr[left]的位置
		if (minPos != left)
			Swap(arr[minPos], arr[left]);
		//更新待排序数据
		left++;
	}
}
 
注意
 这里Swap函数参数使用的是C++的引用,所以不需要传地址
优化直接选择排序
直接选择排序是从一边开始排序,优化后的选择排序可以一趟选出最大值和最小值
 最小值放在待排序数组第一个位置,最大值放在待排序数组最后一个位置,从两头开始排序。
void SelectSort(int* arr, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		int minPos = left;
		int maxPos = left;
		//选出待排序区间最值
		for (int i = left; i <= right; i++)
		{
			if (arr[minPos] > arr[i])
				minPos = i;
			if (arr[maxPos] < arr[i])
				maxPos = i;
		}
		//最大值放在区间末尾
		Swap(arr[maxPos], arr[right]);
		//如果最小值在末尾,修正最小值
		if (minPos == right)
			minPos = maxPos;
		//最小值放在区间首部
		Swap(arr[minPos], arr[left]);
		//更新待排序区间
		left++;
		right--;
	}
}
 
直接选择排序性能分析:
- 无论是直接选择排序还是优化后的直接选择排序时间复杂度都是 O ( n 2 ) O(n^2) O(n2)
 - 空间复杂度均为 O ( 1 ) O(1) O(1)
 - 不稳定
 - 实际生活中很少使用直接选择排序,效率低
 
2. 堆排序
堆排序是根据堆这种数据结构设计的一种算法,他是选择排序的一种。
堆排序的基本思想
- 将待排序数据构建为堆
 - 交换堆顶元素和最后一个元素
 - 对堆进行调整使之满足堆的性质
 - 重复上述过程直至所有元素均有序
 
代码实现
void AdjustDown(int* a, int sz, int parent)
{
	int child = parent * 2 + 1;
	while (child < sz)
	{
		//大堆逻辑-->排升序
		if (child + 1 < sz && a[child] < a[child + 1])
			child++;
		if (a[parent] < a[child])
		{
			Swap(a[parent], a[child]);
			parent = child;
			child = child * 2 + 1;
		}
		else
			break;
	}
}
void HeapSort(int* arr, int sz)
{
	//向下建大堆-->排升序
	for (int i = (sz - 2) / 2; i >= 0; i--)
		AdjustDown(arr, sz, i);
	//排序
	int end = sz - 1;
	while (end > 0)
	{
		Swap(arr[0], arr[end]);
		AdjustDown(arr, end, 0);
		end--;
	}
}
 
关于堆排序详细解释请移步堆的应用



















