归并排序(演化版by数组)

来源:互联网 发布:云南省建设厅官网通知 编辑:程序博客网 时间:2024/06/08 07:07

原始归并排序:
自顶向下:Rsort() 自底向下:sort()

import edu.princeton.cs.algs4.StdOut;import edu.princeton.cs.algs4.StdRandom;public class MergeSort {    private int[] a;    private int[] aux;//辅助   auxiliary    public MergeSort(int[] b)    {        a = new int[b.length];        aux = new int[b.length];        for (int i = 0; i < a.length; ++i)            a[i] = b[i];    }    public MergeSort(int N)    {        a = new int[N];        aux = new int[N];        for (int i = 0; i < a.length; ++i)            a[i] = StdRandom.uniform(-15 * N,15 * N);    }    public void merge(int lo,int mid,int hi)    {        for (int k = lo; k <= hi; ++k)            aux[k] = a[k];        int i = lo,j = mid + 1;        for (int k = lo; k <= hi; ++k)        {            if (i > mid) a[k] = aux[j++];            else if (j > hi) a[k] = aux[i++];            else if (aux[i] > aux[j]) a[k] = aux[j++];            else a[k] = aux[i++];        }    }    public void sort(int lo,int hi)    {        if (hi <= lo) return;        int mid = lo + (hi - lo) / 2;        sort(lo,mid);        sort(mid + 1,hi);        merge(lo,mid,hi);    }    public void Rsort()    {        sort(0,a.length - 1);    }    public void sort()    {        for (int sz = 1; sz < a.length; sz += sz)            for (int lo = 0; lo < a.length - sz; lo += sz+sz)                merge(lo,lo + sz - 1,Math.min(a.length - 1,lo + sz + sz - 1));    }    public void display()    {        for (int i = 0; i < a.length; ++i)            StdOut.print(a[i] + " ");        StdOut.println();    }}

因为我们操作合并的子数组是有序的,如果两个子数组是有序的且a[mid+1]>a[mid]那我们就不必对此部分数组进行归并了,于是我们添加isSorted()检测

import edu.princeton.cs.algs4.StdOut;import edu.princeton.cs.algs4.StdRandom;public class MergeIsSort {    private int[] a;    private int[] aux;    public MergeIsSort(int N)    {        a = new int[N];        aux = new int[N];        for (int i = 0; i < N; ++i)            a[i] = StdRandom.uniform(-15 * N,15 * N);    }    public MergeIsSort(int[] b)    {        a = new int[b.length];        aux = new int[a.length];        for (int i = 0; i < a.length; ++i)            a[i] = b[i];    }    public boolean isSorted(int mid)    {        return a[mid + 1] >= a[mid];    }    public void merge(int lo,int mid,int hi)    {        if (isSorted(mid))            return;        for (int k = lo; k<= hi; ++k)            aux[k] = a[k];        int i = lo,j = mid + 1;        for (int k = lo; k <= hi; ++k)        {            if (i > mid)                a[k] = aux[j++];            else if (j > hi)                a[k] = aux[i++];            else if (aux[i] > aux[j])                a[k] = aux[j++];            else                a[k] = aux[i++];        }    }    public void sort(int lo,int hi)    {        if (hi <= lo) return;        int mid = lo + (hi - lo) / 2;        sort(lo,mid);        sort(mid + 1,hi);        merge(lo,mid,hi);    }    public void Rsort()    {        sort(0,a.length - 1);    }    public void sort()    {        for (int sz = 1; sz < a.length; sz += sz)            for (int lo = 0; lo < a.length - sz; lo += sz + sz)                merge(lo,lo+sz-1,Math.min(a.length - 1,lo+sz+sz-1));    }    public void display()    {        for (int i = 0; i < a.length; ++i)            StdOut.print(a[i] + " ");        StdOut.println();    }}

对于小数组,我们降低归并排序的缺点,可以采用其他排序方法:

import edu.princeton.cs.algs4.StdOut;import edu.princeton.cs.algs4.StdRandom;public class MergeAndInsert {    private int[] a;    private int[] aux;    public MergeAndInsert(int N)    {        a = new int[N];        aux = new int[N];        for (int i = 0; i < N; ++i)            a[i] = StdRandom.uniform(-15 * N,15 * N);    }    public MergeAndInsert(int[] b)    {        a = new int[b.length];        aux = new int[a.length];        for (int i = 0; i < a.length; ++i)            a[i] = b[i];    }    public void merge(int lo,int mid,int hi)    {        for (int k = lo; k <= hi; ++k)            aux[k] = a[k];        int i = lo,j = mid + 1;        for (int k = lo; k <= hi; ++k)        {            if (i > mid)                a[k] = aux[j++];            else if (j > hi)                a[k] = aux[i++];            else if (aux[i] > aux[j])                a[k] = aux[j++];            else                a[k] = aux[i++];        }    }    public void sort(int lo,int hi)    {        if (hi <= lo) return;        if (hi - lo <= 5)        {            InsertSort(lo,hi);            return;        }        int mid = lo + (hi - lo) / 2;        sort(lo,mid);        sort(mid + 1,hi);        merge(lo,mid,hi);    }    public void Rsort()    {        sort(0,a.length - 1);    }    public void sort()    {        int N = a.length;        for (int sz = 1; sz < a.length; sz += sz)            for (int lo = 0; lo < a.length - sz; lo += sz + sz)            {                if (sz <= 5)                {                    InsertSort(lo,Math.min(N -1, lo + sz + sz - 1));                }                else                    merge(lo,lo+sz-1,Math.min(N - 1, lo + sz + sz - 1));            }    }    public void InsertSort(int lo,int hi)    {        for (int i = lo; i < hi; ++i)        {            int j = i + 1;            int temp = a[j];            while (j > lo && temp < a[j - 1])            {                a[j] = a[j - 1];                --j;            }            a[j] = temp;        }    }    public void display()    {        for (int i = 0; i < a.length; ++i)            StdOut.print(a[i] + " ");        StdOut.println();    }}

合并以上行为,我们就得到了优化的归并排序。。。。。

原创粉丝点击