數據結構-十大經典排序算法

常見的內部排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸併排序、快速排序、堆排序、基數排序等。用一張圖歸納:java

 

 冒泡排序

  

算法步驟

比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。算法

對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對。這步作完後,最後的元素會是最大的數。ui

針對全部的元素重複以上的步驟,除了最後一個。blog

持續每次對愈來愈少的元素重複上面的步驟,直到沒有任何一對數字須要比較。排序

Java 代碼實現

import java.util.Arrays;

public class MaoPao {
    public static void main(String[] args){
        int[] arr = {1,45,43,12,91,4,66,82,19,213};
        arr = sort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static int[] sort(int[] sourceArray) {
        // 對 arr 進行拷貝,不改變參數內容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        for (int i = 1; i < arr.length; i++) {
            // 設定一個標記,若爲true,則表示這次循環沒有進行交換,也就是待排序列已經有序,排序已經完成。
            boolean flag = true;

            for (int j = 0; j < arr.length - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;

                    flag = false;
                }
            }

            if (flag) {
                break;
            }
        }
        return arr;
    }
}

選擇排序

  

算法步驟

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。遞歸

再從剩餘未排序元素中繼續尋找最小(大)元素,而後放到已排序序列的末尾。get

重複第二步,直到全部元素均排序完畢。it

 

Java 代碼實現

import java.util.Arrays;

public class XuanZe {
    public static void main(String[] args) {
        int[] arr = {1,45,43,12,91,4,66,82,19,213};
        arr = sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static int[] sort(int[] sourceArray){
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        // 總共要通過 N-1 輪比較
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;

            // 每輪須要比較的次數 N-i
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    // 記錄目前能找到的最小值元素的下標
                    min = j;
                }
            }

            // 將找到的最小值和i位置所在的值進行交換
            if (i != min) {
                int tmp = arr[i];
                arr[i] = arr[min];
                arr[min] = tmp;
            }

        }
        return arr;
    }
}

  

插入排序

算法步驟

將第一待排序序列第一個元素看作一個有序序列,把第二個元素到最後一個元素當成是未排序序列。io

從頭至尾依次掃描未排序序列,將掃描到的每一個元素插入有序序列的適當位置。(若是待插入的元素與有序序列中的某個元素相等,則將待插入元素插入到相等元素的後面。)class

 

Java 代碼實現

import java.util.Arrays;

public class ChaRu {
    public static void main(String[] args) {
        int[] arr = {1,45,43,12,91,4,66,82,19,213};
        arr = sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static int[] sort(int[] sourceArray){
        // 對 arr 進行拷貝,不改變參數內容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        // 從下標爲1的元素開始選擇合適的位置插入,由於下標爲0的只有一個元素,默認是有序的
        for (int i = 1; i < arr.length; i++) {

            // 記錄要插入的數據
            int tmp = arr[i];

            // 從已經排序的序列最右邊的開始比較,找到比其小的數
            int j = i;
            while (j > 0 && tmp < arr[j - 1]) {
                arr[j] = arr[j - 1];
                j--;
            }

            // 存在比其小的數,插入
            if (j != i) {
                arr[j] = tmp;
            }

        }
        return arr;
    }
}

  

快速排序

算法步驟

  1. 從數列中挑出一個元素,稱爲 "基準"(pivot);

  2. 從新排序數列,全部元素比基準值小的擺放在基準前面,全部元素比基準值大的擺在基準的後面(相同的數能夠到任一邊)。在這個分區退出以後,該基準就處於數列的中間位置。這個稱爲分區(partition)操做;

  3. 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序;

 

Java 代碼實現

import java.util.Arrays;

public class KuaiSu {
    public static void main(String[] args) {
        int[] arr = {1,45,43,12,91,4,66,82,19,213};
        arr = sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static int[] sort(int[] sourceArray){
        // 對 arr 進行拷貝,不改變參數內容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        return quickSort(arr, 0, arr.length - 1);
    }

    private static int[] quickSort(int[] arr, int left, int right) {
        if (left < right) {
            int partitionIndex = partition(arr, left, right);
            quickSort(arr, left, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, right);
        }
        return arr;
    }

    private static int partition(int[] arr, int left, int right) {
        // 設定基準值(pivot)
        int pivot = left;
        int index = pivot + 1;
        for (int i = index; i <= right; i++) {
            if (arr[i] < arr[pivot]) {
                swap(arr, i, index);
                index++;
            }
        }
        swap(arr, pivot, index - 1);
        return index - 1;
    }

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

}
相關文章
相關標籤/搜索