选择法排序

选择法排序
选择法排序(Selection Sort)就是通过n-1次关键字间的比较,在从n-i+1 个 选出关键字最小的记录,并和第i(1<= i <=n)个记录交换之。

我们来看代码:

void SelectSort(int *array, int size)
{
	int i;
	for (i = 0; i < size - 1; ++i)
	{
		int j = 1;
		int maxPos = 0;
		for (; j < size - i; ++j)
		{
			if (array[j] > array[maxPos])
				maxPos = j;
		}
		if (maxPos != size - i - 1)
			Swap(&array[size - 1 - i], &array[maxPos]);
	}
}

再来看看实现过程:(程序找的是最大,这里是按最小进行分析的)

(1)i=0,j=0使最小值min等于j=0下标元素,j++向后找比当前min值小就更新min值,循环9次
将最小的min与下标j=0的元素交换
在这里插入图片描述
(2)i=1,j=1使最小值min等于j=1下标的元素,j++向后找比当前min值小就更新min值,循环8次
将最小的min与下标j=1的元素交换
在这里插入图片描述
(3)i=2,j=2使最小值min等于j=2下标的元素,j++向后找比当前min值小就更新min值,循环7次
将嘴的min与下标j=2的元素交换
在这里插入图片描述
(4)i=3,j=3使最小值min等于j=3下标的元素,j++向后找比当前min值小就更新min值,循环6次
将最小的min与下标j=3的元素交换
在这里插入图片描述
(5)i=4,j=4使最小值min等于j=4下标的元素,j++向后找比当前min值小就更新min值,循环5次
将最小的min与下标j=4的元素交换
在这里插入图片描述
(6)i=5,j=5使最小值min等于j=5下标的元素,j++向后找比当前min值小就更新min值,循环4次
将最小的min与下标j=5的元素交换
在这里插入图片描述
(7)i=6,j=6使最小值min等于j=6下标的元素,j++向后找比当前min值小就更新min值,循环3次
将最小的min与下标j=6的元素交换
在这里插入图片描述
(8)由于i=7的时候序列是有序额,所以从i=8,j=8使最小值min等于j=1下标的元素,j++向后找比当前min值小就更新min值,循环1次
将最小的min与下标j=8的元素交换
在这里插入图片描述
(9)排序完成


复杂度分析
从选择排序的过程来看,它最大的特点就是交换移动数据次数相当少,这样也就节约了相应的时间;分析它的时间复杂度发现,无论最好最差的情况,其比较次数都是一样的多,第i躺排序需要进行n-i次关键字的比较,此时需要比较∑(n-i) = n-1 + n-2 +·········+1=n(n-1)/2次;而对于交换次数而言,当最好的时候,交换为0次,最差的时候,也就是降序时,交换次数为n-1次,基于最终的排序时间是比较与交换的次数总和,因此总的时间复杂度依然为O(n²).
尽管与冒泡排序同为O(n²),但选择排序的性能上还是要略优于冒泡排序。


稳定性分析
在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。光说可能有点模糊,来看个小实例:858410,第一遍扫描,第1个元素8会和4交换,那么原序列中2个8的相对前后顺序和原序列不一致了,所以选择排序不稳定。


实现代码

【选择法排序:】

void SelectSort(int *array, int size)
{
	int i;
	for (i = 0; i < size - 1; ++i)
	{
		int j = 1;
		int maxPos = 0;
		for (; j < size - i; ++j)
		{
			if (array[j] > array[maxPos])
				maxPos = j;
		}
		if (maxPos != size - i - 1)
			Swap(&array[size - 1 - i], &array[maxPos]);
	}
}

【选择法排序优化:】

void SelectSort_OP(int *array, int size)
{
	int begin = 0;
	int end = size - 1;
	while (begin < end)
	{
		int minPos = begin;
		int maxPos = begin;

		//找最大于最小元素的位置
		int i = begin + 1;
		while (i <= end)
		{
			if (array[i] > array[maxPos])
				maxPos = i;

			if (array[i] < array[minPos])
				minPos = i;

			++i;
		}

		if (maxPos != end)
			Swap(&array[maxPos], &array[end]);

		//最小的元素有可能在end的位置,重新标记minPos
		if (minPos == end)
			minPos = maxPos;

		if (minPos != begin)
			Swap(&array[minPos], &array[begin]);

		begin++;
		end--;
	}
}
//交换函数
void Swap(int *pLeft, int *pRight)
{
	int tmp = *pLeft;
	*pLeft = *pRight;
	*pRight = tmp;
}

//打印函数
void PrintArray(int *array, int size)
{
	int i = 0;
	for (; i < size; i++)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

#include "Sort.h"

void TestSort()
{
	int array[] = { 2, 0, 4, 9, 3, 6, 8, 7, 1, 5 };
	PrintArray(array, sizeof(array) / sizeof(array[0]));
	//SelectSort(array, sizeof(array) / sizeof(array[0]));
	SelectSort_OP(array, sizeof(array) / sizeof(array[0]));
	PrintArray(array, sizeof(array) / sizeof(array[0]));
}

int main()
{
	TestSort();
	system("pause");
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值