1. 程式人生 > >排序演算法——簡單選擇排序

排序演算法——簡單選擇排序

選擇排序基本思想
在要排序的一組數中,選出最小(或者最大)的一個數與第1個位置的數交換;然後在剩下的數當中再找最小(或者最大)的與第2個位置的數交換,依次類推,直到第n-1個元素(倒數第二個數)和第n個元素(最後一個數)比較為止。
這裡寫圖片描述對陣列{ 8, 5, 2, 6, 9, 3, 1, 4, 0, 7 }排序。

選擇排序是不穩定的排序演算法,在一趟選擇,如果一個元素比當前元素小,而該小的元素又出現在一個和當前元素相等的元素後面,那麼交換後穩定性就被破壞了。 比如序列:{ 3, 7, 3, 2, 6 },一次選擇的最小元素是2,然後把2和第一個3進行交換,從而改變了兩個元素3的相對次序。

java程式碼實現:

package com.lilin.utils;

import java.util.Arrays;

/**
 * 選擇排序
 * 
 * @author lilin
 *
 */
public class SelctionSort {
    /*
     * 實現原理
     * 在要排序的一組數中,選出最小(或者最大)的一個數與第1個位置的數交換;然後在剩下的數當中再找最小(或者最大)的與第2個位置的數交換,依次類推,
     * 直到第n-1個元素(倒數第二個數)和第n個元素(最後一個數)比較為止。
     */
    /**
     * 簡單選擇排序演算法
     * 
     * @param
array * 陣列 * @param n * 排序陣列的前n個數,當n=array.length則表示排序整個陣列。 */
public static void selectSort(int array[], int n) { for (int i = 0; i < n - 1; i++) { int minIndex = i; for (int j = i + 1; j < n; j++) { if
(array[j] < array[minIndex]) { minIndex = j; } } //此處可以將交換順序的程式碼抽取出來,在這裡主要論原理,就不抽取了。 if (minIndex != i) { int temp = array[i]; array[i] = array[minIndex]; array[minIndex] = temp; } System.out.println("第" + (i + 1) + "次排序結果" + Arrays.toString(array)); } System.out.println("選擇排序好陣列" + Arrays.toString(array)); } }

選擇排序平均時間複雜度:O(n²)
選擇排序的交換操作介於 0 和 (n - 1) 次之間。選擇排序的比較操作為 n (n - 1) / 2 次之間。選擇排序的賦值操作介於 0和 3 (n - 1) 次之間。
比較次數O(n²),比較次數與關鍵字的初始狀態無關,總的比較次數N=(n-1)+(n-2)+…+1=n*(n-1)/2。交換次數O(n),最好情況是,已經有序,交換0次;最壞情況交換n-1次,逆序交換n/2次。交換次數比氣泡排序少多了,由於交換所需CPU時間比比較所需的CPU時間多,n值較小時,選擇排序比氣泡排序快。(氣泡排序見後續博文)

上述演算法的一輪的比較中,只取出一個最小值,如果在一輪比較中,同時將最小值和最大值取出,分別和參與比較的陣列中首尾位置交換位置,則可以減少一般比較次數。
具體實現如下

package com.lilin.utils;

import java.util.Arrays;

/**
 * 選擇排序
 * 
 * @author lilin
 *
 */
public class SelctionSort {

    /**
     * 升級版選擇排序演算法(找出最大值和最小值)
     * 
     * @param array
     *            陣列
     * @param n
     *            比較陣列的前n個數,當n=array.length則表示排序整個陣列。
     */
    public static void selectSortUpgrade(int array[], int n) {
        for (int i = 0; i <n/2; i++) {
            int minIndex = i;//記錄最小值位置
            int maxIndex = i;// 記錄最大關鍵字位置

            for (int j = i+1; j <n-i; j++) {
                if (array[j] > array[maxIndex]) {
                    maxIndex = j;
                }
                if (array[j] < array[minIndex]) {
                    minIndex = j;
                }
            }
            //此處可以將交換順序的程式碼抽取出來,在這裡主要論原理,就不抽取了。
            if (minIndex != i) {
                int temp = array[i];
                array[i] = array[minIndex];
                array[minIndex] = temp;
            }
            if (maxIndex != n - i-1) {
                int temp = array[n - i-1];
                array[n -i-1] = array[maxIndex];
                array[maxIndex] = temp;
            }
            System.out.println("第" + (i + 1) + "次排序結果" + Arrays.toString(array));
        }
        System.out.println("選擇排序好陣列" + Arrays.toString(array));
    }

}