8种常见排序算法的java实现

关于常见的排序算法,常用排序算法总结(一)这篇文章写的很详细了,本文主要是把其中的算法用java语言实现一遍

1.冒泡排序

    public static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] + arr[j];
        arr[j] = arr[i] - arr[j];
        arr[i] = arr[i] - arr[j];
    }

    public static void bubbleSort(int[] arr) {
        boolean didSwap;
        for (int i = 0, len = arr.length; i < len - 1; i++) {
            didSwap = false;
            for (int j = 0; j < len - i - 1; j++) {
                if (arr[j + 1] < arr[j]) {
                    swap(arr, j, j + 1);
                    didSwap = true;
                }
            }
            //添加这一步,才能使排序最好O(n)
            if (didSwap == false) {
                return;
            }
        }
    }

    /**
     * 鸡尾酒排序
     * @param a
     * @param n
     */
    public static void cocktailSort(int[] a, int n) {
        int left = 0;                            // 初始化边界
        int right = n - 1;
        while (left < right) {
            for (int i = left; i < right; i++)   // 前半轮,将最大元素放到后面
            {
                if (a[i] > a[i + 1]) {
                    swap(a, i, i + 1);
                }
            }
            right--;
            for (int i = right; i > left; i--)   // 后半轮,将最小元素放到前面
            {
                if (a[i - 1] > a[i]) {
                    swap(a, i - 1, i);
                }
            }
            left++;
        }
    }

2.选择排序

    public static void selectSort(int[] a){
        if(a == null || a.length < 2){
            return;
        }

        for(int i = 0; i < a.length - 1; i++){
            int min = i;
            int minVal = a[i];
            for (int j = i + 1; j < a.length ; j++) {
                if(a[j] < minVal){
                    min = j;
                    minVal = a[j];
                }
            }
            if(min != i){
                a[min] = a[i];
                a[i] = minVal;
            }
        }
    }

3.插入排序

public static void inserSort(int[] nums){
        if(nums == null || nums.length < 2){
            return;
        }

        for (int i = 1; i < nums.length; i++){
            int num  = nums[i];
            int j = i - 1;
            while (j >= 0 && num < nums[j]) {

                    nums[j+1] = nums[j];
                    j--;
            }
            nums[j + 1] = num;
        }
    }


    public static void main(String[] args) {
        int a[] = { 6, 5, 3, 1, 8, 7, 2, 4 }; 
        int n =a.length;
        inserSort(a);
        System.out.println("鸡尾酒排序结果:");
        for (int i = 0; i < n; i++)
        {
            System.out.println("i=" + a[i]);
        }
    }

4.希尔排序

/**
     * 全部元素分为几个区域来提升插入排序的性能。
     * 这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,
     * 算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)
     * 分类 -------------- 内部比较排序
     * 数据结构 ---------- 数组
     * 最差时间复杂度 ---- 根据步长序列的不同而不同。已知最好的为O(n(logn)^2)
     * 最优时间复杂度 ---- O(n)
     * 平均时间复杂度 ---- 根据步长序列的不同而不同。
     * 所需辅助空间 ------ O(1)
     * 稳定性 ------------ 不稳定
     *
     * @param a
     * @param n
     */
    static void shellSort(int a[], int n) {
        int h = 0;
        // 生成初始增量
        while (h <= n / 3)
        {
            h = 3 * h + 1;
        }
        while (h >= 1) {
            for (int i = h; i < n; i++) {
                int j = i - h;
                int get = a[i];
                while (j >= 0 && a[j] > get) {
                    a[j + h] = a[j];
                    j = j - h;
                }
                a[j + h] = get;
            }
            h = (h - 1) / 3;                    // 递减增量
        }
    }

5. 归并排序

/**
 * @description 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
 * 设定两个指针,最初位置分别为两个已经排序序列的起始位置
 * 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
 * 重复步骤3直到某一指针到达序列尾
 * 将另一序列剩下的所有元素直接复制到合并序列尾
 * @date 2018/7/12
 */
public class MergeSort {
    // 分类 -------------- 内部比较排序
    // 数据结构 ---------- 数组
    // 最差时间复杂度 ---- O(nlogn)
    // 最优时间复杂度 ---- O(nlogn)
    // 平均时间复杂度 ---- O(nlogn)
    // 所需辅助空间 ------ O(n)
    // 稳定性 ------------ 稳定
    // 合并两个已排好序的数组A[left...mid]和A[mid+1...right]
    public static void merge(int num[], int left, int mid, int right) {
        int len = right - left + 1;
        int[] tempArray = new int[len];       // 辅助空间O(n)
        int index = 0;
        int i = left;                   // 前一数组的起始元素
        int j = mid + 1;                // 后一数组的起始元素
        while (i <= mid && j <= right) {
            tempArray[index++] = num[i] <= num[j] ? num[i++] : num[j++];  // 带等号保证归并排序的稳定性
        }
        while (i <= mid) {
            tempArray[index++] = num[i++];
        }
        while (j <= right) {
            tempArray[index++] = num[j++];
        }
        for (int k = 0; k < len; k++) {
            num[left++] = tempArray[k];
        }
    }

    /**
     * 递归实现的归并排序(自顶向下)
     */
    public static void mergeSortRecursion(int num[], int left, int right) {
        // 当待排序的序列长度为1时,递归开始回溯,进行merge操作
        if (left == right) {
            return;
        }
        int mid = (left + right) / 2;
        mergeSortRecursion(num, left, mid);
        mergeSortRecursion(num, mid + 1, right);
        merge(num, left, mid, right);
    }

    /**
     * 非递归(迭代)实现的归并排序(自底向上)
     */
    public static void mergeSortIteration(int num[], int len) {
        // 子数组索引,前一个为num[left...mid],后一个子数组为num[mid+1...right]
        int left, mid, right;
        // 子数组的大小i初始为1,每轮翻倍
        for (int i = 1; i < len; i *= 2) {
            left = 0;
            // 后一个子数组存在(需要归并)
            while (left + i < len) {
                mid = left + i - 1;
                // 后一个子数组大小可能不够
                right = mid + i < len ? mid + i : len - 1;
                merge(num, left, mid, right);
                // 前一个子数组索引向后移动
                left = right + 1;
            }
        }
    }

    public static void main(String[] args) {

        int nums[] = {6, 5, 3, 1, 8, 7, 2, 4};      // 从小到大归并排序
        int nums2[] = {6, 5, 3, 1, 8, 7, 2, 4};
        int n1 = nums.length;
        int n2 = nums2.length;
        mergeSortRecursion(nums, 0, n1 - 1);          // 递归实现
        mergeSortIteration(nums2, n2);                 // 非递归实现
        System.out.println("递归实现的归并排序结果:");
        for (int i = 0; i < n1; i++) {
            System.out.println(nums[i]);
        }
        System.out.println();
        System.out.println("非递归实现的归并排序结果:");
        for (int i = 0; i < n2; i++) {
            System.out.println(nums2[i]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/huaixiaozi90/article/details/81061444