选择排序算法详解

选择排序算法详解

选择排序介绍

选择排序的基本思想是: 首先在未排序的数列中找到最小(或最大)元素,然后将其存放到数列的起始位置;接着,再从剩余未排序的元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

选择排序实现

以数列 {20,40,30,10,60,50} 为例,演示选择排序过程:

  • 第1趟(i=0): 找出a1..5中的最小值a3=10,将a0和a3互换 → {10,40,30,20,60,50}
  • 第2趟(i=1): 找出a2..5中的最小值a3=20,将a1和a3互换 → {10,20,30,40,60,50}
  • 第3趟(i=2): 找出a3..5中的最小值,由于该最小值大于a2,不做处理
  • 第4趟(i=3): 找出a4..5中的最小值,由于该最小值大于a3,不做处理
  • 第5趟(i=4): 交换a4和a5 → {10,20,30,40,50,60}

选择排序的时间复杂度和稳定性

时间复杂度

选择排序的时间复杂度是O(N²)。

假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历N-1次,因此选择排序的时间复杂度是O(N²)。

稳定性

选择排序的稳定性有一些争议。数组实现的选择排序是不稳定的,链表实现的选择排序是稳定的。一般提到排序算法时默认是数组实现,所以选择排序被认为是不稳定的。

什么是排序算法的稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中ri=rj且ri在rj之前,排序后ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

代码实现

java 复制代码
/**
 * 选择排序: Java
 */
public class SelectSort {

    /*
     * 选择排序
     * 参数说明:
     *     a -- 待排序的数组
     *     n -- 数组的长度
     */
    public static void selectSort(int[] a, int n) {
        int i;        // 有序区的末尾位置
        int j;        // 无序区的起始位置
        int min;      // 无序区中最小元素位置

        for (i = 0; i < n; i++) {
            min = i;

            // 找出"a[i+1] ... a[n]"之间的最小元素
            for (j = i + 1; j < n; j++) {
                if (a[j] < a[min])
                    min = j;
            }

            // 若min!=i,则交换 a[i] 和 a[min]
            if (min != i) {
                int tmp = a[i];
                a[i] = a[min];
                a[min] = tmp;
            }
        }
    }

    public static void main(String[] args) {
        int[] a = {20, 40, 30, 10, 60, 50};

        System.out.printf("before sort:");
        for (int i = 0; i < a.length; i++)
            System.out.printf("%d ", a[i]);
        System.out.printf("\n");

        selectSort(a, a.length);

        System.out.printf("after  sort:");
        for (int i = 0; i < a.length; i++)
            System.out.printf("%d ", a[i]);
        System.out.printf("\n");
    }
}