插入排序及归并排序java代码实现及详细注释

来源:互联网 发布:excel画出数据形状 编辑:程序博客网 时间:2024/05/19 15:24
public static void main(String[] args) {// 定义无序数组Integer[] arr = new Integer[]{12,14,56,89,11,66,99,3,6,34};// 插入排序前System.out.println("插入排序前");Arrays.asList(arr).forEach(e -> System.out.print(e + "  "));System.out.println("\r\n"+"插入排序后");// 插入排序后:Arrays.asList(insertionSort(arr)).forEach(e -> System.out.print(e + "  "));// 定义无序数组Integer[] arg = new Integer[]{12,14,56,89,11,66,99,3,6,34};// 归并排序前System.out.println("\r\n"+ "归并排序前");Arrays.asList(arg).forEach(e -> System.out.print(e + "  "));// 归并排序后System.out.println("\r\n"+"归并排序后");Arrays.asList(mergeSort(arg)).forEach(e-> System.out.print(e + "  "));}/** * 插入排序  时间复杂度O(n^2) *     思路    (1)当前元素的前面元素均为有序 *        (2)要插入时,从当前元素的左边开始往前找(从后往前找),比当前元素大的元素均往右移一个位置 * @param arr * @return */private static Integer[] insertionSort(Integer[] arr){long start = new Date().getTime();for (int i = 1; i < arr.length; i++) {if (arr[i-1] > arr[i]) {  // 如果 i比前一位小   进行插入操作    int temp = arr[i];    // 记录arr[i]的值int j = i;            // 记录下角标while (j > 0 && temp < arr[j-1]) {  arr[j] = arr[j-1];// 前一位数向后挪一位j--;}arr[j] = temp;}}long end = new Date().getTime();System.out.println("插入排序运行时间  :" + (end - start) + " 毫秒");return arr;}/** * 归并排序   时间复杂度 O(n log n) *      思路   Divide:  把长度为n的输入序列分成两个长度为n/2的子序列。     *        Conquer: 对这两个子序列分别采用归并排序。           *        Combine: 将两个排序好的子序列合并成一个最终的排序序列 * @param arg * @return */private static Integer[] mergeSort(Integer[] arg){long start = new Date().getTime();Integer[] temp = new Integer[arg.length];sort(arg, 0, arg.length);long end = new Date().getTime();System.out.println("程序运行时间  :" + (end - start) + " 毫秒");return arg;}/** * "归" 递归拆分数组  *  * @param numbers * @param pos * @param end */    public static void sort(Integer[] numbers,Integer pos,Integer end){        if ((end - pos) > 1) {                // 递归出口 当数组不可再分时 跳出递归            int offset = (end + pos) >> 1;    // 分成2个数组            sort(numbers, pos, offset);  // 分别取前半部分和后半部分数组进行递归排序            sort(numbers, offset, end);  //  向下递归直到找到叶子节点            merge(numbers, pos, offset, end);  // 合并俩个排好序的数组        }    }    /**     * "并" 将排好序的数组合并     *      * @param numbers     * @param pos     * @param offset     * @param end     */    public static void merge(Integer[] numbers,Integer pos,Integer offset,Integer end){    Integer[] array1 = new Integer[offset - pos];           // array1 为numbers数组前半部分    Integer[] array2 = new Integer[end - offset];// array2 为后半部分        System.arraycopy(numbers, pos, array1, 0, array1.length);      // 从数组源numbers复制数组到 array1        System.arraycopy(numbers, offset, array2, 0, array2.length);   // 从数组源numbers复制数组到 array2        for (int i = pos, j = 0, k = 0; i < end ; i++) {            if (j == array1.length) {                                  // 俩个数组有一个数组元素耗尽(都比较过排好序后)时                System.arraycopy(array2, k, numbers, i, array2.length - k);    // 将另一个数组复制到numbers数组中                break;            }            if (k == array2.length) {                System.arraycopy(array1, j, numbers, i, array1.length - j);                   break;            }            if (array1[j] <= array2[k]) {// 后半部分数组元素跟前半部分比较                 numbers[i] = array1[j++];// 如果前半部分元素小于或等于后半部分元素    numbers数组元素位置不变             } else {// j++ 继续判断 前半部分后一位元素 跟后半部分比较            numbers[i] = array2[k++];// 否则 numbers数组元素 i位元素替换为 后半部分元素             }// k++ 继续判断 后半部分后一位元素 跟前半部分比较        }    }