算法-排序算法思想及實現

排序算法主要有:插入排序,選擇排序,冒泡排序,希爾排序,歸併排序,快速排序,堆排序。這裏的排序指的是內部排序,也就是基於內存的排序,基於內存的排序是基於大O模型的,能夠使用大O模型來衡量算法的性能
摘自我本身的博客園:www.cnblogs.com/myadmin/p/5… 中的部分排序算法。html

插入排序

基本思想:每一步都將一個待排數據按其大小插入到已經排序的數據中的適當位置,直到所有插入完畢。 算法

原始:4 3 1 2
1)    3 4 1 2
2)    1 3 4 2
3)    1 2 3 4複製代碼

核心代碼:shell

/**
     * 插入排序
     */
    public static int[] insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int index = i;// index當前掃描到的元素下標
            int temp = arr[i];
            // 尋找插入的位置
            while (index > 0 && temp < arr[index - 1]) {
                arr[index] = arr[index - 1];
                index--;
            }
            arr[index] = temp;
        }
        return arr;
    }複製代碼

選擇排序

基本思想:從全部序列中先找到最小的,而後放到第一個位置。以後再看剩餘元素中最小的,放到第二個位置……以此類推,就能夠完成整個的排序工做了。能夠很清楚的發現,選擇排序是固定位置,找元素。相比於插入排序的固定元素找位置,是兩種思惟方式。數組

3 2 1 4 6 5

初始化索引位置爲0 
尋找最小值所在位置交換:1 2 3 4 6 5

初始化索引位置爲1
尋找最小值所在位置交換:1 2 3 4 6 5

依次類推!複製代碼

核心代碼:bash

/**
     * 選擇排序
     */
    public static int[] selectSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int minVal = arr[i];
            int index = i;
            for (int j = i + 1; j < arr.length; j++) {// 找到最小元素
                if (arr[j] < minVal) {
                    minVal = arr[j];
                    index = j;
                }
            }
            arr[index] = arr[i];
            arr[i] = minVal;
        }
        return arr;
    }複製代碼

冒泡排序

基本思想:原理是臨近的數字兩兩進行比較,按照從小到大或者從大到小的順序進行交換。
核心代碼:性能

/**
     * 冒泡排序
     * 
     * @param arr
     *            輸入的待排數組
     * @return 返回排序號的數組
     */
    public static int[] bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 1; j < arr.length; j++) {
                if (arr[j - 1] > arr[j]) {
                    int temp = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }複製代碼

希爾排序

基本思想:先取一個小於n的整數d1做爲第一個增量,把文件的所有記錄分組。全部距離爲d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;而後,取第二個增量d2<d1重複上述的分組和排序,直至所取的增量 =1( < …<d2<d1),即全部記錄放在同一組中進行直接插入排序爲止。(下圖來自百度圖片)ui

核心代碼:spa

/**
 * 希爾排序
 * 
 * @author sgl
 * 
 */
public class ShellSort {

    public static int[] shellSort(int[] arr) {
        int step = arr.length / 2;// 初始步長

        while (1 <= step) {
            for (int i = step; i < arr.length; i++) {
                if (arr[i] < arr[i - step]) {
                    int temp = arr[i];
                    arr[i] = arr[i - step];
                    arr[i - step] = temp;
                }
            }
            step = step / 2;
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i]+",");
            }
            System.out.println();
        }

        return arr;
    }複製代碼

歸併排序

基本思想:將待排序序列R[0...n-1]當作是n個長度爲1的有序序列,將相鄰的有序表成對歸併,獲得n/2個長度爲2的有序表;將這些有序序列再次歸併,獲得n/4個長度爲4的有序序列;如此反覆進行下去,最後獲得一個長度爲n的有序序列。
歸併排序其實要作兩件事:
(1)「分解」——將序列每次折半劃分。
(2)「合併」——將劃分後的序列段兩兩合併後排序。指針

核心代碼:code

public static int[] sort(int[] nums, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            sort(nums, low, mid);// 左邊
            sort(nums, mid + 1, high);// 右邊
            merge(nums, low, mid, high);// 左右歸併
        }
        return nums;
    }
    public static void merge(int[] nums, int low, int mid, int high)           {
        int[] temp = new int[high - low + 1];
        int i = low;// 左指針
        int j = mid + 1;// 右指針
        int k = 0;
        // 把較小的數先移到新數組中
        while (i <= mid && j <= high) {
            if (nums[i] < nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
            }
        }
        // 把左邊剩餘的數移入數組
        while (i <= mid) {
            temp[k++] = nums[i++];
        }
        // 把右邊邊剩餘的數移入數組
        while (j <= high) {
            temp[k++] = nums[j++];
        }
        // 把新數組中的數覆蓋nums數組
        for (int k2 = 0; k2 < temp.length; k2++) {
            nums[k2 + low] = temp[k2];
        }
    }

}複製代碼

快速排序

基本思想:快速排序採用的思想是分治思想。
快速排序是找出一個元素(理論上能夠隨便找一個)做爲基準,而後對數組進行分區操做,使基準左邊元素的值都不大於基準值,基準右邊的元素值 都不小於基準值,如此做爲基準的元素調整到排序後的正確位置。遞歸快速排序,將其餘n-1個元素也調整到排序後的正確位置。最後每一個元素都是在排序後的正 確位置,排序完成。因此快速排序算法的核心算法是分區操做,即如何調整基準的位置以及調整返回基準的最終位置以便分治遞歸。

核心代碼:

/**
 * 快速排序
 * 
 * @author sgl
 * 
 */
public class QuickSort {
    static void quicksort(int n[], int left, int right) {
        int dp;
        if (left < right) {
            dp = partition(n, left, right);
            quicksort(n, left, dp - 1);
            quicksort(n, dp + 1, right);
        }
    }

    static int partition(int n[], int left, int right) {
        int pivot = n[left];
        while (left < right) {
            while (left < right && n[right] >= pivot)
                right--;
            if (left < right)
                n[left++] = n[right];
            while (left < right && n[left] <= pivot)
                left++;
            if (left < right)
                n[right--] = n[left];
        }
        n[left] = pivot;
        return left;
    }

}複製代碼
相關文章
相關標籤/搜索