1. 程式人生 > >各路排序神仙理解以及Java實現

各路排序神仙理解以及Java實現

啊啊啊啊啊啊!大話資料結構終於看到了排序這一章章啦,然而各路排序神仙,真的是看懂了!僅僅是看懂了,所以打算用兩天的時間比幾個常見的演算法寫一遍啦,加深一下印象。嚶嚶嚶

氣泡排序

這個演算法我記得是上C語言就接觸了,他的思想是,遇到逆序對,就進行交換啊,就這樣慢慢的第n個有序,第n-1個有序.......全部有序。 關鍵點在於如果一次遍歷,都沒有交換操作的話,那說明已經有序啦,跳出迴圈。排序完成。

package com.it592.sort;

public class BubbleSort extends Sort {
    @Override
    public void sort(int nums[]) {
        int len = nums.length;
        for (int i = 0; i < len; i++){
            boolean flag = true;
            for (int j = 0; j < len - i -1; j++){
                if(nums[j] > nums[j+1]){ // 判斷是否逆序,如果逆序,說明還沒找到正確的位置,繼續後移
                    nums[j] += nums[j+1];
                    nums[j+1] = nums[j] - nums[j+1];
                    nums[j] -= nums[j+1];
                    flag = false;
                }
            }
            if (flag)
                break;
        }
    }
}

選擇排序

選擇排序,按照大話資料結構的話說,其實和氣泡排序差不多,但是這兩個演算法的側重點不同,氣泡排序每次都進行交換操作,其實有很多交換是沒有必要的,畢竟交換也要費點時,選擇排序他只是觀察,找到適合某個位置的點,然後再進行交換,這就好比炒股票,氣泡排序是看到每次漲了之後,都賣出去,然後降了再買點回來,而選擇排序是看到最高點,再拋售,這就省去了中間交易的開銷,也就是氣泡排序時候交換的時候開銷。

package com.it592.sort;

public class SelectSort extends Sort {
    @Override
    public void sort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++){
            int key = i;
            for (int j = i + 1; j < nums.length; j++){ //找到適合i的值。
                    if (nums[key] > nums[j])
                        key = j;
            }
            if(key != i){
                nums[i] += nums[key]; //讓i變為有序的
                nums[key] = nums[i] - nums[key];
                nums[i] -= nums[key];
            }
        }
    }
}

插入排序

插入排序的思想是,假設序列已經有序了,那麼我們只需要把當前元素插入到正確的位置即可。首先,對於第一個元素,因為只有一個元素,所以他是有序的,對於第二個元素,則與第一個元素進行判斷,如果比第一個元素小,則插到第一個元素之前,第一個元素後移;對於第三個元素,則和前兩個元素進行比較,找到合適的位置,插入即可。依次類推,最終有序。

package com.it592.sort;

public class InsertSort extends Sort {
    @Override
    public void sort(int[] nums) {
        int len = nums.length;
        for(int i = 0; i < len -1 ; i++){
            int tmp = nums[i+1];
            int j = i+1;
            for(; j > 0; j--){
                if(nums[j-1] > tmp){
                    nums[j] = nums[j-1];
                }else
                    break;
            }
            nums[j] = tmp;
        }
    }
}

希爾排序

在插入排序中,由於要把某個元素放到合適的位置上,這樣可能就會導致其他元素偏離他本來的位置很遠,希爾排序是對插入排序的一種改進,他可以將小的元素放到前面去,而大的元素集中在尾部。方法是,將陣列進行分組,例如[2,5,1,4,5,55,11,1,15,19,2,33,55,8],我們設定space=3,那麼則[2,11,19,55],[5,5,1,2,8],[1,55,15,33]為三個分組,使用插入排序對他們進行排序後,就會得到以下結果[2,1,1,11,2,15,19,5,33,55,5,55,8],通過這樣一輪排序之後,就會發現小的部分相對集中在前面,而大數則集中在後面。最終迴圈完畢,有序

package com.it592.sort;

public class ShellSort extends Sort {
    @Override
    public void sort(int[] nums) {
        int gap = nums.length / 3 + 1;

        while (true){
                for (int i = 0; i < nums.length - gap; i += gap){
                    int tmp = nums[i+gap];
                    int j = i + gap;
                    for (; j > 0; j -= gap){
                        if(nums[j-gap] > tmp)
                            nums[j] = nums[j-gap];
                        else
                            break;
                    }
                    nums[j] = tmp;
                }
                if (gap == 1)
                    break;
                gap = gap / 3 + 1;

        }
    }
}