对简单排序的二次改进

简单选择排序的思想是每次从中选出最小(或者最大)的一个元素,然后把该元素与当前list的最前面的元素交换,直至剩下最后一个元素时,排序完毕

对简单选择排序的改进,主要是在选择时,可以同时将当前list中的最大list[max]和最小元素list[min]都找出来,然后将最小元素与当前list中的首元素交换,然后再将最大的元素与当前list中的最后一个元素交换,直至最后一组元素交换完毕,整个排序结束。这样的话仅需要原来的一半。

举个栗子,对于一个无序 的list={49,38,65,97,76,13,27,49,55,4},

1、找到当前最大的97和当前最小的4,将4交换到首位,将97交换到末位


2、找到从38到55区间段的最大值76和最小值13,将13交换到38的位置,将76交换到55的位置


3、找到从65到最后一个49区间段的最大值65和最小值27,将65交换到49的位置,将27交换到65的位置,注意,这时候的交换顺序为:

首先交换27到65处:4 13 27 55 38 65 49 76 97,这时候最大的65已经被交换走了,所以不能直接用记录的最大值的位置list[2]去交换,因为65是与最小值27交换的,所以65的真实位置是找到的list[min],所以只需要list[min]与当前的最后一个元素49交换即可。


4、找到从49(前)到49(后)的最大值55和最小值38,将38与49(前)交换,将55和49(前)交换


5、最后发现从49到49只剩下两个元素,并且相等,故不需要交换,最后的排序结果即为:


注意:

实现思路:1、找到当前list的最大元素list[max]和最小元素list[min]

  2、将最大元素list[max]和最小元素list[min]插入到当前的首位和末位

插入技巧

如果最小元素list[min]不等于当前list的首位:

{

将最小元素与首位元素交换

如果当前list首元素与最大元素相等(最小元素在交换时已经将最大元素从首位换掉了):

{

再将list[min]与当前list的末位元素交换即可完成最大元素的位置交换

}

否则:

直接交换最大元素list[max]与当前list的末位元素

}

否则:

直接交换最大元素list[max]与当前list的末位元素


交换技巧

如果两个元素不相等,则进行交换,如果相等,则不做任何处理


其代码实现如下:

#include <stdio.h>
#include <stdlib.h>

void swap(int *a,int *b)
{
    int t;
    if(*a != *b)
    {
        printf("交换元素%d和%d\n",*a,*b);
        t = *a;
        *a = *b;
        *b = t;
    }
}

void getNum(int array[],int len,int start,int end)
{
    int i,j;
    int max = array[start];
    int pMax = start;
    int min = array[start];
    int pMin = start;
    int t;
    for(i=start;i<=end;i++)
    {
        if(max < array[i])
        {
            max = array[i];
            pMax = i;
        }
         if(min > array[i])
        {
            min = array[i];
            pMin = i;
        }
    }
    printf("--------------------------------第%d次----------------------\n",(start+1));
    printf("最小的元素array[%d] = %d\n",pMin,array[pMin]);
    printf("最大的元素array[%d] = %d\n",pMax,array[pMax]);

   /* printf("当前首元素array[%d] = %d\n",start,array[start]);
    printf("当前末尾元素array[%d] = %d\n",end,array[end]);
*/
    if(array[start] != array[pMin])
    {
        swap(&array[start],&array[pMin]);
        if(array[start] == array[pMax])
        {
            swap(&array[end],&array[pMin]);
        }else{
            swap(&array[end],&array[pMax]);
        }
    }else{
        swap(&array[pMax],&array[end]);
    }
}

void showList(int array[],int len)
{
    int i;
    for(i=0;i<len;i++)
        printf("%d   ",array[i]);
    printf("\n");
}

void sortList(int list[],int len)
{
     int i,j;
    for(i=0,j=len-1;i<len/2;i++,j--)
    {
        getNum(list,len,i,j);
        showList(list,len);
    }
}

int main()
{
    int list[10] = {49,38,65,97,76,13,27,49,55,4};
    showList(list,10);
    int len=10;

    sortList(list,len);

    showList(list,len);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值