归并排序(非递归,Java实现)

归并排序(非递归):

public class MergeSort {
    /**
     * @param arr   待排序的数组
     * @param left  本次归并的左边界
     * @param mid   本次归并的中间位置,也就是分界线
     * @param right 本次归并的右边界
     * @param <T>   泛型
     * @local aux   辅助空间(Auxiliary Space)
     */
    private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
        T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);

        int i = left;
        int j = mid + 1;

        for (int t = left; t <= right; t++) {
            if (i > mid) {
                arr[t] = aux[j++ - left];
            } else if (j > right) {
                arr[t] = aux[i++ - left];
            } else if (aux[i - left].compareTo(aux[j - left]) < 0) {
                arr[t] = aux[i++ - left];
            } else {
                arr[t] = aux[j++ - left];
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
        int n = arr.length;
        for (int size = 1; size < n; size *= 2) {
            for (int i = 0; i < n - size; i += size * 2) {
                merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, n - 1));
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static void printArr(Object[] arr) {
        for (Object o : arr) {
            System.out.print(o);
            System.out.print("\t");
        }
        System.out.println();
    }

    public static void main(String args[]) {
        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
        printArr(arr);//3   5   1   7   2   9   8   0   4   6
        sort(arr);
        printArr(arr);//0   1   2   3   4   5   6   7   8   9
    }
}

归并排序(非递归)优化:

merge前判断是否有必要进行归并

public class MergeSort {
    /**
     * @param arr   待排序的数组
     * @param left  本次归并的左边界
     * @param mid   本次归并的中间位置,也就是分界线
     * @param right 本次归并的右边界
     * @param <T>   泛型
     * @local aux   辅助空间(Auxiliary Space)
     */
    private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
        T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);

        int i = left;
        int j = mid + 1;

        for (int t = left; t <= right; t++) {
            if (i > mid) {
                arr[t] = aux[j++ - left];
            } else if (j > right) {
                arr[t] = aux[i++ - left];
            } else if (aux[i - left].compareTo(aux[j - left]) < 0) {
                arr[t] = aux[i++ - left];
            } else {
                arr[t] = aux[j++ - left];
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
        int n = arr.length;
        for (int size = 1; size < n; size *= 2) {
            for (int i = 0; i < n - size; i += size * 2) {
                if (arr[i + size - 1].compareTo(arr[i + size]) > 0) {
                    merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, n - 1));
                }
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static void printArr(Object[] arr) {
        for (Object o : arr) {
            System.out.print(o);
            System.out.print("\t");
        }
        System.out.println();
    }

    public static void main(String args[]) {
        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
        printArr(arr);//3   5   1   7   2   9   8   0   4   6
        sort(arr);
        printArr(arr);//0   1   2   3   4   5   6   7   8   9
    }
}

递归排序(非递归)继续优化:对小规模数据使用插入排序

归并排序是对一组一组的数据进行归并。当这一组中的数很少时(暂定为4),使用插入排序。

public class MergeSort {
    /**
     * @param arr   待排序的数组
     * @param left  本次归并的左边界
     * @param mid   本次归并的中间位置,也就是分界线
     * @param right 本次归并的右边界
     * @param <T>   泛型
     * @local aux   辅助空间(Auxiliary Space)
     */
    private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
        T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);

        int i = left;
        int j = mid + 1;

        for (int t = left; t <= right; t++) {
            if (i > mid) {
                arr[t] = aux[j++ - left];
            } else if (j > right) {
                arr[t] = aux[i++ - left];
            } else if (aux[i - left].compareTo(aux[j - left]) < 0) {
                arr[t] = aux[i++ - left];
            } else {
                arr[t] = aux[j++ - left];
            }
        }
    }

    private static <T extends Comparable<? super T>> void insertionSort(T[] arr, int left, int right) {
        for (int i = left + 1; i <= right; i++) {
            T temp = arr[i];
            int j = i - 1;
            while (j >= left && temp.compareTo(arr[j]) < 0) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = temp;
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
        int len = arr.length;

        int smallSize = 4;//当规模小于4时采用插入排序

        for (int i = 0; i < len; i += smallSize) {
            insertionSort(arr, i, Math.min(i + smallSize - 1, len - 1));
        }

        for (int size = smallSize; size < len; size *= 2) {
            for (int i = 0; i < len - size; i += size * 2) {
                if (arr[i + size - 1].compareTo(arr[i + size]) > 0){
                    merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, len - 1));
                }
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static void printArr(Object[] arr) {
        for (Object o : arr) {
            System.out.print(o);
            System.out.print("\t");
        }
        System.out.println();
    }

    public static void main(String args[]) {
        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
        printArr(arr);//3   5   1   7   2   9   8   0   4   6
        sort(arr);
        printArr(arr);//0   1   2   3   4   5   6   7   8   9
    }
}

  

时间: 2024-10-14 02:48:23

归并排序(非递归,Java实现)的相关文章

归并排序-非递归应用

/** function:     合并2个有序数组,有效到大     input:     数组first pData[begin..mid]     数组second pData[mid+1..end]     output:pData[begin...end]          需要空间:o(n) **/ void merge(int *pData,int begin,int mid,int end) {     int pTemp[8]={0};     int first =begin

归并排序 非递归 不回写

#include<iostream>using namespace std;void Merge(int a[],int b[],int first,int mid,int last)//合并两个有序数组{ int p=first,q=mid+1; int pos=first; while(p<=mid&&q<=last) { if(a[p]<a[q]) { b[pos++]=a[p++]; } else { b[pos++]=a[q++]; } } if(p

数据结构--汉诺塔--借助栈实现非递归---Java

1 /*汉诺塔非递归实现--利用栈 2 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 3 * 2.先进栈,在利用循环判断是否栈空, 4 * 3.非空情况下,出栈,检查是否只有一个盘子--直接移动,否则就模拟前面递归的情况--非1的情况 5 * 4.直到栈空就结束循环,就完成全部的移动. 6 * */ 7 class Stack11{ 8 Towers[] tt = new Towers[20]; 9 int top = -1; 10 11 public boolean i

最容易理解的二叉树后续遍历非递归java实现

后续遍历要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈.如果P不存在左孩子和右孩子,则可以直接访问它:或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点.若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问. java private static void postOrderNonRecursiveEasily(Node root) {

归并排序的递归与非递归实现java

package com.edu.hpu.sort.merge; import com.edu.hpu.sort.Sort; public class MergeSort extends Sort { @Override public int[] doSort(int[] arr) { return mergeSort2(arr, 0, arr.length - 1); } @SuppressWarnings("unused") private int [] mergeSort(int

【书上讲解】归并排序的非递归写法

描述 [题解] 让区间的长度L为1,2,4,...2^(n-1) 然后对每个位置i开始的长度为L的区间归并有序,用归并排序的方法就好,然后i跳转到i+L 复杂度仍然是log2(n)*n级别的,注意写的时候的一些细节. 比如一定要让最后L>=n的情况进行过一次,不然无法保证整个序列是有序的 [代码] /* 归并排序非递归写法 */ #include <cstdio> const int N = 1e5; int a[N+10],b[N+10]; int n; //把a这个数组在l1..r2

【Java】 归并排序的非递归实现

归并排序可以采用递归方法(见:归并排序),但递归方法会消耗深度位O(longn)的栈空间,使用归并排序时,应该尽量使用非递归方法.本文实现了java版的非递归归并排序. 更多:数据结构与算法合集 思路分析 递归排序的核心是merge(int[] arr, int start, int mid, int end)函数,讲[start~mid-1]和[mid~end]部分的数据合并,递归代码是使用递归得到mid,一步步分解数组. 非递归时,我们直接定义要合并的小数组长度从1开始,在较小的长度数组都合

归并排序 - 递归非递归实现java

1.归并排序思想: 以2路归并为例,一个有n个记录的序列可以看作n个长度为1的有序子序列,将其两两合并成n/2(向上取整)个长度为2或1的有序序列,当有奇数个记录时为1,重复归并,直到得到一个长度为n的有序序列. 2.归并排序的复杂度: 递归:时间复杂度O(nlongn),空间复杂度O(n+longn) 非递归:时间复杂度O(nlongn),空间复杂度O(n) 所以用到归并排序,还是优先考虑非递归吧.  3.递归实现 1 public void mergeSort1(int[] data){ 2

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr