选择排序算法(十)

选择排序算法是通过每一步选取最小值或最大值来达到排序的目的。

假设有N个数字:

2 5 3 6 4 

如果按选择排序来的话,可以先从前面开始,也可以从后面开始。这里从前面开始比较。

第一步:用2跟其它数字比较,如果有比它小,就把它放在第一位,但是这里没有,所以2还是在第一位;

第二步:把2排除,因为它已经排好了,是最小的,所以从5开始依次往后比较,3比5小,所以后面用3去比较,3是最小的,把它放在第二位;

第三步:经过第二步,5被交换到了第三位,还是用5去跟后面的数字比较,得到最小的4,放在第三位;

第四步:经过第三步,5被换到了第5位,6和5比较,得到较小的5,放在第四位;

经过N-1步比较排序,得到了正确的排列顺序:

2 3 4 5 6

因此,选择排序就是每一步都选取出来里面最小的值或最大的值,其实这里也可以进行一次判断,判断是否排序在中间的某一步就完成了,也就不需要N-1步了,提高效率。

【选取最大值】

for (i=0;i<len-1;i++)//比较次数
	{
		k = i;
		for (j=i+1;j<len;j++)
		{
			if (a[j] >= a[k])//将第一个数与剩下的数进行比较
				k = j;//得到最大的值的下标
		}
		if (k!=i)//用来排序第一个位子放最大值还是最小值
		{
			temp = a[i];//进行交换,把最大值换到前面去
			a[i] = a[k];
			a[k] = temp;
		}
外层循环为比较次数,内层循环进行比较,注释也比较清楚就不再一一解释了。


【选取最小值】

for (i=len-1; i>0; i--)
	{
		k = i;
		for (j = i-1; j>=0; j--)//求得最小值
		{
			if (a[j] <= a[k])//将第一个数与剩下的数进行比较
				k = j;//得到最小的值的下标
		}
		if (k != i)//把最小值换到最后去
		{
			temp = a[i];//进行交换
			a[i] = a[k];
			a[k] = temp;
		}

【判断排序是否结束】

int num = 0;
		for (int i = 0; i<len - 1; i++)
		{
			if (a[i] >= a[i + 1])
				num++;
		}
		if (num == len - 1)
		{
			return;
		}
判断相邻数字是否是按正确的顺序排列,如果是就加1,进行统计,通过统计比较次数是否等于N-1来判断是否排序结束。


【代码示例】

/*选择排序法必须进行n-1次比较,效率比较慢*/
#include <iostream>
#include <stdlib.h>
#include <time.h>

//#define SIZE 10//数组大小
//从前往后进行比较
void SelectionSort(int *a,int len)//选择法排序
{
	int i, j, k, h;
	int temp;//交换临时变量

	for (i=0;i<len-1;i++)//比较次数
	{
		k = i;
		for (j=i+1;j<len;j++)
		{
			if (a[j] >= a[k])//将第一个数与剩下的数进行比较
				k = j;//得到最大的值的下标
		}
		if (k!=i)//用来排序第一个位子放最大值还是最小值
		{
			temp = a[i];//进行交换,把最大值换到前面去
			a[i] = a[k];
			a[k] = temp;
		}
		printf("第%d步排序结果为:",i+1);
		for (h=0;h<len;h++)
		{
			printf("%d ",a[h]);
		}
		printf("\n");
		int num = 0;
		for (int i = 0; i<len - 1; i++)
		{
			if (a[i] >= a[i + 1])
				num++;
		}
		if (num == len - 1)
		{
			return;
		}
	}
}
//从后往前进行比较
void SelectionSort2(int *a, int len)//选择法排序
{
	int i, j, k, h,n=1;
	int temp;//交换临时变量

	for (i=len-1; i>0; i--)
	{
		k = i;
		for (j = i-1; j>=0; j--)//求得最小值
		{
			if (a[j] <= a[k])//将第一个数与剩下的数进行比较
				k = j;//得到最小的值的下标
		}
		if (k != i)//把最小值换到最后去
		{
			temp = a[i];//进行交换
			a[i] = a[k];
			a[k] = temp;
		}
		printf("第%d步排序结果为:",n++);
		for (h = 0; h<len; h++)
		{
			printf("%d ", a[h]);
		}
		printf("\n");
		int num = 0;
		for (int i=0;i<len-1;i++)
		{
			if (a[i] >= a[i + 1])
			num++;
		}
		if (num==len-1)
		{
			return ;
		}
		
	}
}

void main()
{
	using namespace std;
	int i;
	int SIZE;
	cout << "请输入待排序数字的个数:";
	cin >> SIZE;
	int *shuzu = new int[SIZE];
	int *shuzu2 = new int[SIZE];
	//int shuzu[SIZE];
	//int shuzu2[SIZE];
	srand(time(NULL));
	for (i=0;i<SIZE;i++)
	{
		shuzu[i] = rand() / 1000;
		shuzu2[i] = shuzu[i];
	}
	printf("排序前:\n");
	for (i=0;i<SIZE;i++)
	{
		printf("%d ",shuzu[i]);
	}
	printf("\n");

	SelectionSort(shuzu,SIZE);
	printf("排序后:\n");
	for (i=0;i<SIZE;i++)
	{
		printf("%d ",shuzu[i]);
	}
	printf("\n");

	printf("排序前:\n");
	for (i = 0; i<SIZE; i++)
	{
		printf("%d ", shuzu[i]);
	}
	printf("\n");

	SelectionSort2(shuzu2, SIZE);
	printf("排序后:\n");
	for (i = 0; i<SIZE; i++)
	{
		printf("%d ", shuzu2[i]);
	}
	printf("\n");

	system("pause");
}

【演示结果】




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值