選擇排序(Selection Sort)原理及Java實現

選擇排序(Selection Sort )分爲兩種 簡單選擇排序(Simple Selection Sort) 和樹形選擇排序。


簡單選擇排序(Simple Selection Sort):

簡單選擇排序類似於冒泡排序(Bubble Sort) ,每次都會在剩下的元素集合中選擇出一個最值出來填充到當前位置。唯一的區別是,冒泡排序在每次發現比當前值小於(或大於)時,都會交換元素的位置, 而 簡單選擇排序是選擇剩餘元素中的最值和當前位置交換數據。

比如對於元素集合R={37, 40, 38, 42, 461, 5,  7, 9, 12} 

在第一趟排序中:37直接和5交換, 形成新的序列 R1={5,40,38,42,461,37,7,9,12}

在第二趟排序中:40直接和7交換, 形成新的序列 R2={5,7,38,42,461,37,40,9,12}

以此類推,直到最後一個元素(注意:在第二趟排序中,38比42小,但是他們並沒有交換數據)。

以下是簡單選擇排序的一個Java實現版本:

public static void selectionSort(int[] data) {
        if (data == null || data.length <= 1)
            return;
        int i, j, value, minPos, len = data.length;
        int outer = len - 1, tmp;
        for (i = 0; i < outer; i++) {
            value = data[i];
            minPos = -1;
            for (j = i + 1; j < len; j++) {
                if (data[j] < value) {
                    minPos = j;
                    value = data[j];
                }
            }
            if (minPos != -1) {
                tmp = data[i];
                data[i] = value;
                data[minPos] = tmp;
            }
            
//            for (int k = 0; k < len; k++) {
//                System.out.print(data[k] + " , ");
//            }
//            System.out.println();
        }
    }

    public static void main(String[] args) {
        int[] coll = {
                37, 40, 38, 42, 461, 5,  7, 9, 12
        };
        selectionSort(coll);
        for (int i = 0; i < coll.length; i++) {
            System.out.print(coll[i] + " , ");
        }
    }

樹選擇排序(Tree Selection Sort)

樹選擇排序算法相對於簡單選擇排序來說是典型的以空間換時間的算法。其思想是對待排序的 N 個元素 , 構造出相對較小的 (n+1)/2個數,然後再構造出相對較小的[n+1]/4個數,直到只有一個元素爲止。構造成一個完全二叉樹。

排序的時候,那個元素就是最小的,取出該最小元素,將該元素替換爲"最大值",再調整完全二叉樹。

下面是樹形選擇排序的一個Java實現版:

public static void treeSelectionSort(int[] data) {
        if (data == null || data.length <= 1)
            return;
        int len = data.length , low = 0 , i , j;
        // add Auxiliary Space
        int[] tmp = new int[2*len -1];
        int tSize = tmp.length;
        //construct a tree
        for(i =len-1 , j=tmp.length-1;i >=0 ;i--,j--){
            tmp[j]=data[i];
        }
        for(i = tSize -1 ; i > 0 ; i-=2){
            tmp[(i-1)/2] = tmp[i] > tmp[i-1]? tmp[i-1]:tmp[i];
        }
        //end
        //remove the minimum node.
        while(low < len){
            data[low++] = tmp[0];
            for(j=tSize-1;tmp[j]!=tmp[0];j--);
            tmp[j] = Integer.MAX_VALUE;
            while(j > 0){
                if(j%2 == 0){  //如果是右節點
                    tmp[(j-1)/2] = tmp[j] > tmp[j-1]?tmp[j-1]:tmp[j];
                    j = (j-1)/2;
                }else{  //如果是左節點
                    tmp[j/2]=tmp[j] > tmp[j+1]? tmp[j+1]:tmp[j];
                    j = j/2;
                }
            }
        }
    }
在構造完全二叉樹的時候對 N 個元素的集合, 需要 2*N -1 個輔助空間。

代碼:

 while(j > 0){
                if(j%2 == 0){  //如果是右節點
                    tmp[(j-1)/2] = tmp[j] > tmp[j-1]?tmp[j-1]:tmp[j];
                    j = (j-1)/2;
                }else{  //如果是左節點
                    tmp[j/2]=tmp[j] > tmp[j+1]? tmp[j+1]:tmp[j];
                    j = j/2;
                }
            }
則實現遞歸的構造新集合中的最小值。


發佈了89 篇原創文章 · 獲贊 12 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章