排序之简单选择排序

简单选择排序

爱炒股票短线的人,总是喜欢不断的买进卖出,想通过价差来实现盈利。但通常这种频繁操作的人,即使失误不多,也会因为操作的手续费和印花税过高而获利很少。还有一种做股票的人,他们很少出手,只是在不断的观察和判断,等到时机一到,果断买进或卖出。他们因为冷静和沉着,以及交易的次数少,而最终收益颇丰。

冒泡排序的思想就是不断地在交换,通过交换完成最终的排序,这和做股票短线频繁操作的人是类似的。我们可不可以像只有在时机非常明确到来时才出手的股票高手一样,也就是在排序时找到合适的关键字再做交换,并且只移动一次就完成相应关键字的排序定位工作呢?这就是选择排序法的初步思想。

选择排序的基本思想是每一趟在n-i+1(i=1,2,…,n-1)个记录中选取关键字最小的记录作为有序序列的第i个记录。

1.简单选择排序算法

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

代码如下:

/* 对顺序表L作简单选择排序 */
void SelectSort(SqList *L) {
	int i, j, min, temp;
	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]的值 */
            temp = L->r[i];
            L->r[i] = L->r[min];
            L->r[min] = temp;                   
    }
}

代码很简单,针对待排序的关键字序列是 {9,1,5,8,3,7,4,6,2},对 i 从 1 循环到 8。当 i=1 时,L.r[i]=9,min 开始是 1,然后与 j=2 到 9 比较 L.r[min] 与 L.r[j] 的大小,因为 j=2 时最小,所以min=2。最终交换了 L.r[2] 与 L.r[1] 的值。注意,这里比较了8次,却只交换数据操作一次,如图 :

在这里插入图片描述

当i=2时,L.r[i]=9,min 开始是 2,经过比较后,min=9,交换 L.r[min] 与 L.r[i] 的值。这样就找到了第二位置的关键字。如图:

在这里插入图片描述

当 i=3 时,L.r[i]=5,min 开始是 3,经过比较后,min=5,交换 L.r[min] 与 L.r[i] 的值。如图:

在这里插入图片描述

以此类推。。。

2.简单选择排序复杂度分析

从简单选择排序的过程来看,它最大的特点就是交换移动数据次数相当少,这样也就节约了相应的时间。分析它的时间复杂度发现,无论最好最差的情况,其比较次数都是一样的多,第 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),但简单选择排序的性能上还是要略优于冒泡排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值