简单选择排序

爱炒股票短线的人,总是喜欢不断的买进卖出,想通过价差来实现盈利。但通常这种频繁操作的人,即使失误不多,也会因为操作的手续费和印花税过高而获利很少。还有一种做股票的人,他们很少出手,只是在不断的观察和判断,等到时机一到,果断买进或卖出。他们因为冷静和沉着,以及交易的次数少,而最终收益颇丰。
冒泡排序的思想就是不断地在交换,通过交换完成最终的排序,这和做股票短线频繁操作的人是类似的。我们可不可以像只有在时机非常明确到来时才出手的股票高手一样,也就是在排序时找到合适的关键字再做交换,并且只移动一次就完成相应关键字的排序定位工作,这就是选择排序法的初步思想。
选择排序的基本思想是每一趟在n-i+1(i=1,2,...,n-1)个记录中选取关键字最小的记录作为有序序列的第i个记录。我们这里先介绍的是简单选择排序法。

简单选择排序算法


简单选择排序法(Simple Selection Sort)就是通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1≤i≤n)个记录交换之。
我们来看代码。

/*  对顺序表L作简单选择排序  */
void  SelectSort(SqList  *L)
{
int  i,  j,  min;
for  (i  =  1;  i  <  L->length;  i++)
{
/*  将当前下标定义为最小值下标  */
min  =  i;                  
/*  循环之后的数据  */
for  (j  =  i  +  1;  j  <=  L->length;  j++)        
{
/*  如果有小于当前最小值的关键字  */
if  (L->r[min]  >  L->r[j]) 
/*  将此关键字的下标赋值给min  */
min  =  j;                  
}
/*  若min不等于i,说明找到最小值,交换  */
if  (i  !=  min)            
/*  交换L->r[i]与L->r[min]的值  */
swap(L,  i,  min);          
}}


代码应该说不难理解,针对待排序的关键字序列是{9,1,5,8,3,7,4,6,2},对i从1循环到8。

对顺序表L进行简单选择排序的功能。

首先,从顺序表L的第2个元素开始,依次遍历到最后一个元素(i的取值范围为1到L的长度-1)。 在每一次遍历中,设当前下标为i的元素为最小值(用min记录最小值的下标)。 然后,再从下一个元素开始(j的取值范围为i+1到L的长度),遍历到最后一个元素,找到比当前最小值更小的元素,将其下标赋值给min。 如果min不等于i,则说明找到了比当前位置更小的元素,需要进行交换操作。 最后,将L的第i个元素与L的第min个元素进行交换。

简单选择排序的基本思想是,每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为排序序列的第一个元素,直到所有待排序的数据元素排完为止。具体实现上,通过循环遍历找到当前位置之后的最小值,然后将它与当前位置交换,即可实现排序。

时间复杂度:O(n^2) ,其中n为顺序表L的长度。 空间复杂度:O(1) ,只需要常数个额外的空间用于存储临时变量。 稳定性:不稳定,因为相等元素的相对位置可能发生改变。

简单选择排序复杂度分析


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

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值