十大排序算法之 选择排序

118 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

稳定性定义

排序算法的稳定性,是说待排序的对象序列中。存在排序关键字相等的对象,经过算法排序后,这些相等的对象能够保持相对位置不变化,就说明排序算法是稳定,否则是不稳定的。

选择排序 思路: 从待排序序列中选择最小/大的数字放到最左侧,重复n-1次,完成无序序列为有序序列。

选择排序是不稳定排序,会造成对象的相对次序更改,时间复杂度较差,最好 最差和平均时间复杂度都是O(N2)。不太适合太大数据量排序。

流程: 比较序列N个数,选择其中最小的数值,与第一个数值交换位置,于是第一个位置排序完成。
从第二个位置起往后选择最小值,与序列第二个位置交换位置,于是排序完成两个位置。
循环这个操作,直到完成N-1个位置,排序完成。

代码演示:

#include<stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include <string.h>
#include <errno.h>

int Cnt = 0;
int NumArr[200] = {0};

void PrintNums()
{
    for(int i = 0;i < Cnt;i++){
        fprintf(stdout," %d-",NumArr[i]);
    }
}

int main(int argc, char** argv)
{
    if(argc == 1) {
        fprintf(stderr,"%s:need a some arg\n",argv[0]);
        exit(1);
    }
    int CntTemp = Cnt = argc -1;

    for(int i = 0;i < Cnt;i++){
        NumArr[i] = atoi(argv[i+1]);
    }
   
    fprintf(stdout,"inputNum:");
    PrintNums();
    fprintf(stdout,"\n");

    int inxBuf = 0;
    int ValTemp = 0;
    for(int a = 0;a < Cnt;a++){
        inxBuf = a;
        for(int b = a;b < Cnt;b++){
            if(NumArr[inxBuf] > NumArr[b]){
                inxBuf = b;
            }
            ValTemp = NumArr[inxBuf];
            NumArr[inxBuf] = NumArr[a];
            NumArr[a] = ValTemp;
        }
    }

    fprintf(stdout,"result:");
    PrintNums();
    fprintf(stdout,"\n");
    return 0;

}

编译脚本makefile使用冒泡排序文中使用的脚本。 排序结果:

image.png

思路上和冒泡算法比较相似。冒泡在比较的过程中会频繁发生交换位置操作,而许多的交换是无效的。所以效率上选择排序更好一点。选择排序更符合人的思维习惯,理解起来更简单点。
优化方案,在选择最小值的循环中,可以增加一个选择最大值的操作,这样两头一起排序,只需要循环N/2次。