本文参考资料:书籍《大话数据结构》,微信公众号:码农有道。
选择排序介绍
选择排序是一种简单的排序算法,它的基本原理是:将一个未排序的数列中的元素依次进行比较,把最大或最小值放在第一位,然后再将剩下的未排序的数列元素进行比较,最小值或最大值放在第二个位置;以此类推,直到数列中的元素按照一定的方式拍好序(从大到小或从小到大排列)。
选择排序原理图解
以数列{20,40,30,10,60,50}为例,演示其选择排序过程(如下图)。
排序流程如下:
第1次:i=0。找出a[1...5]中的最小值a[3]=10,然后将a[0]和a[3]互换。 数组变化:20,40,30,10,60,50 -- > 10,40,30,20,60,50
第2次:i=1。找出a[2...5]中的最小值a[3]=20,然后将a[1]和a[3]互换。 数组变化:10,40,30,20,60,50 -- > 10,20,30,40,60,50
第3次:i=2。找出a[3...5]中的最小值,由于该最小值大于a[2],该趟不做任何处理。
第4次:i=3。找出a[4...5]中的最小值,由于该最小值大于a[3],该趟不做任何处理。
第5次:i=4。交换a[4]和a[5]的数据。 数组变化:10,20,30,40,60,50 -- > 10,20,30,40,50,60
选择排序代码
#include<stdio.h> #define MAXSIZE 10 //用于排序的数组个数的最大值,可修改 #define OK 1 #define TRUE 1 #define FALSE 0 typedef int Status; //定义一个用于排序的顺序表结构 typedef struct { int r[MAXSIZE]; int length; //用于记录顺序表的长度 }SqList; //交换数组中下标为i和j的元素值 void swap(SqList *L,int i,int j){ int temp; temp = L->r[i]; L->r[i] = L->r[j]; L->r[j] = temp; return OK; } //对顺序表L做简单的选择排序 void SelectSort(SqList *L){ int i , j ,min; for(i = 0; i < L->length; i++){ min = i; //将当前下标定义成最小值下标 for(j = i + 1; j < L->length; j++){ if(L->r[min] > L->r[j]){ //如果小于当前最小值的关键字 min = j; //将此关键字的下标赋值为min } } if(min != i){ swap(L,i,min); } } }
算法复杂度和稳定性分析
选择排序的时间复杂度是O(N2):假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?N-1次因此,选择排序的时间复杂度是O(N2)。
选择排序是稳定的算法,它满足稳定算法的定义:假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
尽管选择排序和冒泡排序复杂度相同,但是由于选择排序减少了数据交换的次数,所以在性能上要优于冒泡排序。