选择排序详解及C++实现

选择排序

选择排序是一种简单直接的排序算法,其实质是在未排序序列中找到最小(大)元素,将其放在已排序序列的末尾(开始)位置。

算法步骤

以每次找到最大元素的方法为例:

  1. 从前到后,在未排序序列中查找最大元素,将该最大元素与序列末尾数据进行交换;
  2. 再从剩余未排序元素中继续寻找最大元素,将该最大元素与已排序序列前一个元素进行交换,即将该元素放在已排序序列开始的位置;
  3. 重复第2步,直到所有元素均排序完毕。

算法描述

//arrPtr为指向数组的指针,arrLen为数组长度
void selection_sort(int* arrPtr, int arrLen)
{
	if (!arrPtr)
		return;

	for (int i = arrLen - 1; i > 0; --i)
	{
		int maxIndex = 0;//每次排序默认第一个元素为最大元素
		int j = 0;
		for (; j <= i; ++j)
		{
			//更新当前未排序序列中最大元素的index
			if (arrPtr[j] > arrPtr[maxIndex])
				maxIndex = j;
		}
		//当最大元素不是当前比较序列中最后一个元素时,交换当前比较序列最后一个元素与最大元素的位置
		if (maxIndex != j - 1)
			swap(arrPtr, maxIndex, j - 1);
	}
}

上述算法中swap函数是为了交换数组中两元素位置的函数,其实现在前一篇《冒泡排序详解》博客中有详细实现,读者需要可翻看一下那篇博客。

排序过程演示

选择排序详解及C++实现_第1张图片

算法分析

时间复杂度

假定数组元素个数:n,比较次数:C,交换次数:M。
选择排序每趟都需要通过比较来定位当前未排序序列中的最大值,其总的比较次数为:C=(n-1) + (n-2) + … + 1 = n(n-1)/2
若所有元素均正序排列,则每趟比较后不需要发生交换,此时交换次数Mmin=0。
若所有元素均反序排列,则每趟比较后均需发生一次交换,此时交换次数均为:Mmax=n-1
综上,冒泡排序平均时间复杂度为O(n2),但其交换次数比冒泡排序少很多,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

算法稳定性

选择排序每次从前到后寻找最大元素的位置,若两个元素相等,只会记录到第一个元素为最大元素,并将该元素交换到已排序序列开始位置;下一轮比较时找到刚才相等的另一元素,也将该元素交换到已排序序列开始位置;也就是说对于相同元素,原序列中先出现的元素在排序后成为排序序列中后出现的元素,前后顺序发生了变化,所以选择排序是一种不稳定排序算法。

你可能感兴趣的:(排序算法,排序算法,选择排序,时间复杂度)