经典排序算法实现

和自甴很熟 提交于 2020-03-26 00:53:21

冒泡排序
选择排序
插入排序
快速排序
堆排序
希尔排序
归并排序


//java 版本
package com.leej.sort;


public class SortAlgorithm {
    //冒泡排序, 稳定, On^2
    public static void BubbleSort(int[] nums) {
        int n = nums.length;
        for (int step = 1; step < n; step++) {
            boolean changed = false;
            for (int j = 0; j < n - step; j++) {
                if (nums[j] > nums[j + 1]) {
                    swap(nums, j, j + 1);
                    changed = true;
                }
            }

            if (!changed) return;
        }
    }

    //选择排序, 不稳定 On^2
    public static void SelectSort(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (nums[minIndex] > nums[j])
                    minIndex = j;
            }
            if (minIndex != i) swap(nums, i, minIndex);
        }
    }

    //插入排序, 稳定, On^2
    public static void InsertSort(int[] nums) {
        int n = nums.length;
        for (int i = 1; i < n; i++) {
            int tmp = nums[i];
            int j;
            for (j = i; j > 0; j--) {
                if (nums[j - 1] > tmp) {
                    nums[j] = nums[j-1];
                }
                else break;
            }
            nums[j] = tmp;
        }
    }

    //快排, 不稳定, Onlogn, On^2
    public static void QuickSort(int[] nums, int left, int right) {
        if (left >= right) return;
        int pIndex = partition(nums, left, right);
        QuickSort(nums, left, pIndex - 1);
        QuickSort(nums, pIndex + 1, right);
    }
    private static int partition(int[] nums, int left, int right) {
        if (left >= right) return left;
        int pivot = nums[left];
        while(left < right) {
            while(left < right && nums[right] >= pivot) right--;
            nums[left] = nums[right];

            while(left < right && nums[left] < pivot) left++;
            nums[right] = nums[left];
        }
        nums[left] = pivot;
        return left;
    }

    //堆排序 不稳定 Onlogn
    public static void HeapSort(int[] nums) {
        int n = nums.length;
        for (int i = n/2 - 1; i >= 0; i--) {
            MaxHeapify(nums, i, n - 1);
        }
        for (int i = n - 1; i > 0; i--) {
            swap(nums, 0, i);
            MaxHeapify(nums, 0, i - 1);
        }
    }
    private static void MaxHeapify(int[] nums, int start, int end) {
        int father = start;
        int son = father * 2 + 1;
        while(son <= end) {
            if (son + 1 <= end && nums[son + 1] > nums[son]) son++;
            if (nums[father] >= nums[son]) return;
            swap(nums, father, son);
            father = son;
            son = father * 2 + 1;
        }
    }

    //希尔排序 不稳定 On^1.5
    public static void ShellSort(int[] nums) {
        int gap = 1, i, j, len = nums.length;
        int temp;
        while(gap < len / 3) gap = gap * 3 + 1;
        for (; gap > 0; gap /= 3) {
            for (i = gap; i < len; i++) {
                temp = nums[i];
                for (j = i - gap; j >= 0 && nums[j] > temp; j -= gap)
                    nums[j + gap] = nums[j];
                nums[j + gap] = temp;
            }
        }
    }

    //归并排序 稳定 Onlogn
    public static void MergeSort(int[] nums) {
        if (nums.length <= 1) return;
        int[] result = new int[nums.length];
        MergeSortRecursive(nums, result, 0, nums.length - 1);
    }
    private static void MergeSortRecursive(int[] nums, int[] reg, int start, int end) {
        if (start >= end) return;
        int len = end - start, mid = (len >> 1) + start;
        int start1 = start, end1 = mid;
        int start2 = mid + 1, end2 = end;
        MergeSortRecursive(nums, reg, start1, end1);
        MergeSortRecursive(nums, reg, start2, end2);

        int k = start;
        while (start1 <= end1 && start2 <= end2)
            reg[k++] = nums[start1] < nums[start2] ? nums[start1++] : nums[start2++];
        while (start1 <= end1)
            reg[k++] = nums[start1++];
        while (start2 <= end2)
            reg[k++] = nums[start2++];
        for (k = start; k <= end; k++)
            nums[k] = reg[k];
    }


    public static void showNums(int[] nums) {
        for (int num : nums)
            System.out.print(num + " ");
        System.out.println();
    }

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

    public static void main(String[] args) {
        int[] nums = new int[] {1,3,2,3,4,2,7,5};
        showNums(nums);
        //quickSort(nums, 0, nums.length - 1);
        //BubbleSort(nums);
        //SelectSort(nums);
        //InsertSort(nums);
        //HeapSort(nums);
        //ShellSort(nums);
        MergeSort(nums);
        showNums(nums);
    }
}

References

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!