天天看點

資料結構基礎加強之排序算法

資料結構基礎加強之排序算法

冒泡排序-Bubble Sort

思想:做升序排列,通過相鄰兩數之間兩兩交換,讓大的數先冒出來,到數組的尾部,小的數後冒出來。

圖例:

排序之前:

資料結構基礎加強之排序算法

第一次循環後:

資料結構基礎加強之排序算法

代碼實作:

public class BubbleSort {

    public static void main(String[] args) {
        int[] array = { , , , , , , , ,  };
        solution(array);
    }

    // 冒泡排序升序排列
    private static void solution(int[] array) {
        for (int i = ; i < array.length - ; i++) {
            for (int j = ; j < array.length - ; j++) {
                if (array[j] > array[j + ]) { // 相鄰2個數比較如果前值大于後值則交換
                    swap(array, j + , j);
                }
            }
        }
        for (int i : array) {
            System.out.print(i + " ");
        }
    }

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

插入排序 -Insert Sort

思想:每次将一個記錄插入到已經排好序的有序表中,進而得到新的有序表。

将序列的第一個記錄看成有序的子序列,從第二個記錄開始逐個進行插入,直到整個序列有序。

圖例:

排序之前:

資料結構基礎加強之排序算法

第一次排序後:

資料結構基礎加強之排序算法

因為數組第二個位置和第一個位置之間是有序的是以不變化。

第三次排序後:

資料結構基礎加強之排序算法

第三個數和第二個交換,使前三個數有序。

代碼實作:

public class InsertSort {

    public static void main(String[] args) {
        int[] array = { , , , , , , , ,  };
        solution(array);
    }

    // 插入排序升序排列
    private static void solution(int[] array) {
        for (int i = ; i < array.length; i++) {
            int cur = array[i];
            int j = i - ;
            while (j >= ) {
                int k = j;
                if (array[j] < cur) {
                    break;
                } else {
                    array[++k] = array[j];
                }
                j--;
            }
            array[++j] = cur;
        }
        for (int i : array) {
            System.out.print(i + " ");
        }
    }
}
           

選擇排序 -Select Sort

思想:每次找一個最小值。放到數組的起始位置。

即從起始位置,每次循環選擇未排序的第一個值作為哨兵,依次與後面的值比較,如果哨兵小,則兩兩交換,直至數組最後一個位置,此時哨兵位置的數為最小值。

圖例:

排序之前:

資料結構基礎加強之排序算法

第一次排序之後:

資料結構基礎加強之排序算法

數組最後一個位置的值比第一個位置的小,兩兩交換,數組最小值放到第一個位置。

代碼實作:

public class SelectSort {

    public static void main(String[] args) {
        int[] array = { , , , , , , , ,  };
        solution(array);
    }

    // 選擇排序升序排列
    private static void solution(int[] array) {
        for (int i = ; i < array.length; i++) {
            for (int j = i + ; j < array.length; j++) {
                if (array[i] > array[j]) {
                    swap(array, i, j);
                }
            }
        }
        for (int i : array) {
            System.out.print(i + " ");
        }
    }

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

希爾排序 -Shell Sort

思想:對直接插入排序的改進,選擇一個增量序列{size/2,t1,…..,1}。

根據對應的增量ti,将待排序列分割成若幹長度為m 的子序列,分别對各子表進行直接插入排序,依次減小增量,當增量因子為1時,整個序列作為一個表處理。

圖例:

排序前:

資料結構基礎加強之排序算法

第一次排序之後:因為數組長為9,是以初始增量為4

資料結構基礎加強之排序算法

代碼實作:

public class ShellSort {

    public static void main(String[] args) {

        int[] array = { , , , , , , , ,  };
        solution(array);
    }
    // 希爾排序實作升序排列
    private static void solution(int[] array) {
        int size = array.length;
        for (int i = size / ; i >= ; i--) {
            for (int j = ; j < array.length; j++) {
                if ((j + i) < array.length) {
                    if (array[j] > array[j + i]) {
                        swap(array, j, j + i);
                    }
                }
            }
        }
        for (int i : array) {
            System.out.print(i + " ");
        }
    }
    // 數組2個元素的交換
    private static void swap(int[] array, int j, int i) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}
           

歸并排序 -Merge Sort

思想:使用分治法解決問題,每一次将數組對分,依次遞歸,直至每個數組隻有一個元素,此時數組是有序的,然後将分開的數組,相鄰兩兩之間合并,直至最後得到有序的數組。

圖例:

資料結構基礎加強之排序算法

代碼實作:

public class MergeSort {

    public static void main(String[] args) {
        int[] array = { , , , , , , , ,  };
        int i = ;
        int j = array.length - ;
        solution(array, i, j);
        for (int e : array) {
            System.out.print(e + " ");
        }
    }
    private static void solution(int[] array, int left, int right) {
        int mid = (right + left) / ;
        if (left < right) {
            solution(array, left, mid); // 左邊
            solution(array, mid + , right); // 右邊
            merge(array, left, mid, right);// 歸并
        }
    }
    // 歸并實作升序排列
    private static void merge(int[] array, int left, int mid, int right) {
        int[] temp = new int[right - left + ];
        int i = left;
        int j = mid + ;
        int k = ; // temp數組索引
        while (i <= mid && j <= right) { // 填入2數組中較小的值
            if (array[i] < array[j]) {
                temp[k] = array[i];
                k++;
                i++;
            } else {
                temp[k] = array[j];
                k++;
                j++;
            }
        }
        // 左邊數組剩餘填入
        while (i <= mid) {
            temp[k++] = array[i++];
        }
        // 右邊數組剩餘填入
        while (j <= right) {
            temp[k++] = array[j++];
        }
        for (int index = ; index < temp.length; index++) {
            array[index + left] = temp[index];
        }
    }
}
           

快速排序 -Quick Sort

思想:采用分治法,每次找一個基準值,對數組處理,讓小于基準值的位于基準值的左邊,大于基準值的位于基準值的右邊。然後對左右兩邊做遞歸處理。

圖例:每次取第一個值為基準值

排序之前:

資料結構基礎加強之排序算法

第一次排序之後:

資料結構基礎加強之排序算法

代碼實作:

public class QuickSort {

    public static void main(String[] args) {
        int[] array = { , , , , , , , ,  };
        int low = ;
        int high = array.length - ;
        solution(array, low, high);
        for (int i : array) {
            System.out.print(i + " ");
        }
    }

    // 遞歸實作升序快速排序
    private static void solution(int[] array, int low, int high) {
        if (low < high) {
            int i = low;
            int j = high;
            int curr = array[i];
            while (i < j) {
                while (curr <= array[j] && i < j) {
                    j--;
                }
                if (i < j) {
                    array[i] = array[j];
                    i++;
                }
                while (curr >= array[i] && i < j) {
                    i++;
                }
                if (i < j) {
                    array[j] = array[i];
                    j--;
                }
            }
            array[i] = curr;
            solution(array, low, i - );
            solution(array, i + , high);
        }
    }
}
           

基數排序-Radix Sort

思想:桶排序的一種。讓個位、十位、百位的大小依次對數組進行排序。

圖例:

資料結構基礎加強之排序算法

代碼實作:

public class RadixSort {

    public static void main(String[] args) {

        int[] array = { , , , , , , , ,  };
        solution(array);
        for (int i : array) {
            System.out.print(i + " ");
        }
    }

    private static void solution(int[] array) {
        int maxPos = getMaxPos(array);
        int[][] temp = new int[][array.length + ]; // 臨時數組 按元素位 上的數值大小 依次存儲元素
        for (int i = ; i < temp.length; i++) {
            temp[i][] = ; // 記錄行内元素的個數 初始化為0
        }
        for (int pos = ; pos < maxPos; pos++) {
            for (int index = ; index < array.length; index++) {
                int row = getPos(array[index], pos);
                int col = ++temp[row][];
                temp[row][col] = array[index];
            }
            // 收集元素
            for (int row = , i = ; row < ; row++) {
                for (int col = ; col <= temp[row][]; col++) {
                    array[i++] = temp[row][col];
                }
                temp[row][] = ; // 恢複行元素數記錄 下次繼續使用
            }
        }
    }

    // 取出數組元素在目前Pos上的數 pos = 1:個位 pos = 2:十位...
    private static int getPos(int cur, int pos) {
        int temp = ;
        for (int i = ; i < pos - ; i++) {
            temp = temp * ;
        }
        return (cur / temp) % ;
    }

    // 得到數組中最大元素的位數
    private static int getMaxPos(int[] array) {

        int max = array[];
        for (int i = ; i < array.length; i++) {
            if (max < array[i]) {
                max = array[i];
            }
        }
        int result = ;
        int temp = ;
        while (true) {
            temp = temp * ;
            if (max / temp != ) {
                result++;
            } else {
                break;
            }
        }
        return result;
    }

}
           

堆排序 -Heap Sort

基本思想:基于最小堆或者最大堆。對給定的數組建立堆,依據堆對數組排序

具體說明可以參考:http://blog.csdn.net/a815060271/article/details/72328745

各個排序算法之間的比較

各排序算法穩定性,時間複雜度,空間複雜度分析:

資料結構基礎加強之排序算法

具體代碼可以參考:https://github.com/Li-JY/algorithm-and-datastructure/tree/master/src/sort

繼續閱讀