冒泡排序、選擇排序、快速排序、插入排序、希爾排序、歸併排序、基數排序以及堆排序

1、冒泡排序 - 依次比較相鄰兩元素,若前一元素大於後一元素則交換之,直至最後一個元素即爲最大;然後重新從首元素開始重複同樣的操作,直至倒數第二個元素即爲次大元素;依次類推。如同水中的氣泡,依次將最大或最小元素氣泡浮出水面。

實現代碼就是兩個for循環,然後比較交換位置

時間複雜度:O(N2)

 

2、選擇排序 - 首先初始化最小元素索引值爲首元素,依次遍歷待排序數列,若遇到小於該最小索引位置處的元素則刷新最小索引爲該較小元素的位置,直至遇到尾元素,結束一次遍歷,並將最小索引處元素與首元素交換;然後,初始化最小索引值爲第二個待排序數列元素位置,同樣的操作,可得到數列第二個元素即爲次小元素;以此類推。

簡單的說:一次遍歷找出最小的元素,將最小的元素放在最前面,第二次就找出第二小的,交換第二個位置,以此類推。

時間複雜度:O(N2)  

3、快速排序 - (類似於選擇排序的定位思想)選一基準元素,依次將剩餘元素中小於該基準元素的值放置其左側,大於等於該基準元素的值放置其右側;然後,取基準元素的前半部分和後半部分分別進行同樣的處理;以此類推,直至各子序列剩餘一個元素時,即排序完成(類比二叉樹的思想,from up to down)

時間複雜度:O(NlogN) 

import java.util.Arrays;

public class QuickSort {
    public static void main(String[] args) {
        int[] a = {1, 2, 4, 5, 7, 4, 5, 3, 9, 0};
        System.out.println(Arrays.toString(a));
        quickSort(a);
        System.out.println(Arrays.toString(a));
    }

    public static void quickSort(int[] a) {
        if (a.length > 0) {
            quickSort(a, 0, a.length - 1);
        }
    }

    private static void quickSort(int[] a, int low, int high) {
        //1,找到遞歸算法的出口
        if (low > high) {
            return;
        }
        //2, 存
        int i = low;
        int j = high;
        //3,key
        int key = a[low];
        //4,完成一趟排序
        while (i < j) {
            //4.1 ,從右往左找到第一個小於key的數
            while (i < j && a[j] > key) {
                j--;
            }
            // 4.2 從左往右找到第一個大於key的數
            while (i < j && a[i] <= key) {
                i++;
            }
            //4.3 交換
            if (i < j) {
                swap(a,i,j);
            }
        }
        // 4.4,調整key的位置
        swap(a,i,low);

        //5, 對key左邊的數快排
        quickSort(a, low, i - 1);
        //6, 對key右邊的數快排
        quickSort(a, i + 1, high);
    }

    private static void swap(int[] a, int i, int j) {
        int p = a[i];
        a[i] = a[j];
        a[j] = p;
    }
}

4、插入排序 - 數列前面部分看爲有序,依次將後面的無序數列元素插入到前面的有序數列中,初始狀態有序數列僅有一個元素,即首元素。在將無序數列元素插入有序數列的過程中,採用了逆序遍歷有序數列,相較於順序遍歷會稍顯繁瑣,但當數列本身已近排序狀態效率會更高。

時間複雜度:O(N2) 

5、希爾排序 - 插入排序的改進版。爲了減少數據的移動次數,在初始序列較大時取較大的步長,通常取序列長度的一半,此時只有兩個元素比較,交換一次;之後步長依次減半直至步長爲1,即爲插入排序,由於此時序列已接近有序,故插入元素時數據移動的次數會相對較少,效率得到了提高。

時間複雜度:通常認爲是O(N3/2) 

6、基數排序 - 桶排序的改進版,桶的大小固定爲10,減少了內存空間的開銷。首先,找出待排序列中得最大元素max,並依次按max的低位到高位對所有元素排序;桶元素10個元素的大小即爲待排序數列元素對應數值爲相等元素的個數,即每次遍歷待排序數列,桶將其按對應數值位大小分爲了10個層級,桶內元素值得和爲待排序數列元素個數。

時間複雜度:O(x*N) 

7、歸併排序 - 採用了分治和遞歸的思想,遞歸&分治-排序整個數列如同排序兩個有序數列,依次執行這個過程直至排序末端的兩個元素,再依次向上層輸送排序好的兩個子列進行排序直至整個數列有序(類比二叉樹的思想,from down to up)。

時間複雜度:O(NlogN)  

8、堆排序 - 堆排序的思想藉助於二叉堆中的最大堆得以實現。首先,將待排序數列抽象爲二叉樹,並構造出最大堆;然後,依次將最大元素(即根節點元素)與待排序數列的最後一個元素交換(即二叉樹最深層最右邊的葉子結點元素);每次遍歷,刷新最後一個元素的位置(自減1),直至其與首元素相交,即完成排序。

時間複雜度:O(NlogN) 

9、桶排序 - 實現線性排序,但當元素間值得大小有較大差距時會帶來內存空間的較大浪費。首先,找出待排序列中得最大元素max,申請內存大小爲max + 1的桶(數組)並初始化爲0;然後,遍歷排序數列,並依次將每個元素作爲下標的桶元素值自增1;最後,遍歷桶元素,並依次將值非0的元素下標值載入排序數列(桶元素>1表明有值大小相等的元素,此時依次將他們載入排序數列),遍歷完成,排序數列便爲有序數列。

時間複雜度:O(x*N)  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章