初等排序之选择排序

     本打算昨晚把选择排序写了,不过昨晚写完希尔排序,有点晚,就在今早写了~

    选择排序,顾名思义,就是不断选择剩余数列中的最大值,然后再进行排序,是一个比较简单的排序算法,所以就直接以一个实例用图像的方式介绍下:

初始数列如下:

在进行选择排序时,是在无序区中选择最大或者最小值,然后与无序区中的第一个元素进行交换,例如这里初始化整个数列都是无序区,最小值是1,就会与开头的5的进行交换,交换过程如下:

在交换后,1变成有序区中的一个元素,接着在剩下的元素构成的无序区中继续进行选择排序:

之后的交换过程依次如下列步骤:



要注意这次的插入排序,在无序区中,队首的8的已经是最小值,这时不用进行交换,这时便已经排序结束,整个排序的结果如下:


整个过程非常简单。具体的实现则是在每一趟排序时,初始化最小值的下标minIndex为无序区中的第一个元素的下标,之后在进行选择时,遇到比A[minIndex]更小的值,就进行更新minIndex,不断更新minIndex后,在每一趟的最后,进行判断minIndex还是不是无序区中队首元素的下标,如果不是说明无序区中队首元素不是无序区中最小的元素,这时就将队首元素与A[minIndex]进行交换,具体的代码如下:

#include<stdio.h>
void Selection_Sort(int A[],int N)
{
	for(int i=0;i<N-1;i++)
	{
		int  minIndex=i;
		for(int j=i;j<N;j++)
		{
			if(A[j]<A[minIndex])
			   minIndex=j;            //记录下这趟中关键码最小的数据的下标  
		}
		if(minIndex!=i)      
		{           //如果这趟找到的最小数据不是这趟查找的开头数据,则交换
		  int temp=A[i];
		  A[i]=A[minIndex];
		  A[minIndex]=temp;
	    } 
	}
}
int main()
{
	int A[100],N;
	scanf("%d",&N);
	for(int i=0;i<N;i++)
	  scanf("%d",&A[i]);
	Selection_Sort(A,N);
	for(int i=0;i<N;i++)
	   printf("%d ",A[i]);
	   return 0;
} 


除了这种利用下标的选择排序,其实还有一种利用元素值的选择排序,主要的实现就是初始化最小值为无序区中的队首元素,然后从队首元素下一个开始,每一个都与队首元素进行比较,如果小于队首元素,则直接进行交换,而不是记录下标。这种选择插入的方式,保证每次比较时,无序区中队首元素都是目前最小的元素,而且每一趟可能交换的次数不止一次,这样就会大大降低程序的效率,而第一种记录下标的选择排序每一趟只需要交换一次甚至不需要交换。

以下是利用元素值的选择排序源代码,大家参考以下即可:

#include<stdio.h>
void Selection_Sort2(int A[],int N)
{
	for(int i=0;i<N-1;i++)
	{
		for(int j=i+1;j<N;j++)
		{
			if(A[j]<A[i])
			{
		           int temp=A[i];
		           A[i]=A[j];
		           A[j]=temp;
			}
		}
		  
	}
}
int main()
{
	int A[100],N;
	scanf("%d",&N);
	for(int i=0;i<N;i++)
	  scanf("%d",&A[i]);
	Selection_Sort2(A,N);
	for(int i=0;i<N;i++)
	   printf("%d ",A[i]);
	   return 0;
} 

PS:到这,初等排序的内容就介绍完,当然排序还不止这些,像堆排序,归并排序,快速排序等都是比较常用的排序,不过就比较复杂了,那些会在之后进行介绍~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值