Natural Merge Sort(自然归并排序)

This is a Natural Merge Sort program from my textbook. It works, but I don‘t think it‘s good.

// Natural merge sort program in the textbook

public class NaturalMergeSortProgram {

    public static void main(String[] args)
    {
        int a[] = new int[10000000];
        int b[] = new int[a.length];
        for (int i = 0; i < a.length; i++)
            a[i] = (int)(1+Math.random()*(100-0+1));
        long starTime=System.currentTimeMillis();
        NaturalMergeSort(a, b);
        long endTime=System.currentTimeMillis();
        long Time = endTime - starTime;
        System.out.println("executing time: "+Time+"(ms)");
        /*for (int i = 0; i < b.length; i++)
        {    if (i % 20 == 0)
                System.out.println();
            System.out.print(a[i]+" ");
        }*/
    }

    public static void NaturalMergeSort(int a[], int b[])
    {    // merge array a into b and then b into a until sorted
        while (!MergeRuns(a, b) & !MergeRuns(b, a));
    }

    public static boolean MergeRuns(int a[], int b[])
    {
        int i = 0, k = 0;
        int n = a.length;
        boolean asc = true;
        int x;
        while (i < n)
        {
            k = i;
            do
                x = a[i++];
            while (i < n && x <= a[i]);        // elements are increasing

            while (i < n && x >= a[i])        // elements are decreasing
                x = a[i++];
            merge(a, b, k , i-1, asc);
            asc = !asc;
        }
        return k == 0;
    }

    public static void merge(int a[], int b[], int low, int high, boolean asc)
    {    // merge a[low:high] into b[low:high]
        int k = asc ? low : high;
        int c = asc ? 1 : -1;
        int i = low, j = high;
        while (i <= j)
        {
            if (a[i] <= a[j])
                b[k] = a[i++];
            else
                b[k] = a[j--];
            k += c;
        }
    }

}

Or maybe I don‘t get it? Because it‘s rather obscure and lack of comments( these comments are all added by me).

So I decide to write my own Natural Merge Sort program:

// My own natural merge sort program

public class MyNaturalMergeSort {

    public static void main(String args[]) {
        int a[] = new int[10000000];
        int b[] = new int[a.length];
        for (int i = 0; i < a.length; i++)
            a[i] = (int)(1+Math.random()*(100-0+1));
        long starTime=System.currentTimeMillis();
        while (!NaturalMergeSort(a, b) & !NaturalMergeSort(b, a));
        long endTime=System.currentTimeMillis();
        long Time = endTime - starTime;
        System.out.println("executing time: "+Time+"(ms)");
        /*for (int i = 0; i < a.length; i++)
            System.out.print(a[i]+" ");
        System.out.println();
        */
    }

    public static boolean NaturalMergeSort(int x[], int y[]) {
        // find the two adjacent natural increasing arrays x[l:m] and x[m+1:r],
        // then merge them into y[l:r] using function merge()
        int i, l, m = 0, r;
        for (i = 0; i < x.length; i++)
        {    l = i;
            while ((i < x.length-1) && (x[i] <= x[i+1]))    // get x[l:m]
                i++;
            m = i++;
            if (m == x.length-1)        // the whole array is sorted
                return true;
            while ((i < x.length-1) && (x[i] <= x[i+1]))    // get x[m+1:r]
                i++;
            r = i;
            merge(x, y, l, m, r);
        }
        return false;    // the whole array is not yet sorted
    }

    public static void merge(int x[], int y[], int l, int m, int r) {
        // merge x[l:m] and x[m+1:r] into y[l:r]
        int i = l,
            j = m+1,
            k = l;
        while ((i <= m) && (j <= r))
            if (x[i] <= x[j])
                y[k++] = x[i++];
            else
                y[k++] = x[j++];
        while (k <= r)
            if (i > m)    // elements in x[l:m] are all merged into array y[]
                y[k++] = x[j++];
            else
                y[k++] = x[i++];

    }
}

After running each program for 3 times, I got the executing time as below:

program in textbook -- 1205ms 1261ms 1260ms

my program -- 202ms 203ms 198ms

Wow! My program is bad-ass! At least better than the one in textbook. This makes me exciting!

And through this practice, I came to know there‘s a lot of fun hacking the algorithm. I‘m looking forword to write more beautiful and efficient code!

时间: 2024-10-25 12:44:16

Natural Merge Sort(自然归并排序)的相关文章

排序 起泡排序(bubble sort),归并排序(merge sort)

1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换,就说明前区已经有序了,直接终止了.但是有个效率低下的地方,就是右边界hi是每次循环向前移动一个单元 跳跃版,在提前终止版的基础上,解决右边界hi移动效率低下的问题.解决思路:每次循环后,记录下最后一次的交换位置A,然后让hi=交换位置A,所以hi就可以跳跃移动多个单元了. 基本版代码实现 //冒泡排序(基本版 效率低下) template<typename T> void Vect

[算法]——归并排序(Merge Sort)

归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlogn),但是归并排序除了递归调用间接使用了辅助空间栈,还需要额外的O(n)空间进行临时存储.从此角度归并排序略逊于快速排序,但是归并排序是一种稳定的排序算法,快速排序则不然. 所谓稳定排序,表示对于具有相同值的多个元素,其间的先后顺序保持不变.对于基本数据类型而言,一个排序算法是否稳定,影响很小,但是

排序算法二:归并排序(Merge sort)

归并排序(Merge sort)用到了分治思想,即分-治-合三步,算法平均时间复杂度是o(nlgn). (一)算法实现 1 private void merge_sort(int[] array, int first, int last) { 2 if (first + 1 < last) { 3 int mid = (first + last) / 2; 4 merge_sort(array, first, mid); 5 merge_sort(array, mid, last); 6 7 /

经典排序算法 - 归并排序Merge sort

经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 4 1 5 9] 先看一下每一个步骤下的状态,完了再看合并细节 第一步 [6 2 4 1 5 9]原始状态 第二步 [2 6] [1 4] [5 9]两两合并排序,排序细节后边介绍 第三步 [1 2 4 6] [5 9]继续两组两组合并 第四步 [1 2 4 5 6 9]合并完成,排序完成 输出结

1.7 逆序数与归并排序[inversion pairs by merge sort]

[本文链接] http://www.cnblogs.com/hellogiser/p/inversion-pairs-by-merge-sort.html [题目] 编程之美1.7光影切割问题可以进一步将问题转化为求逆序数问题. [分析] 求解逆序对问题与MergeSort类似,只需要对MergeSort稍作修改即可实现.MergeSort是采用分治法的思想,若需要排序A[p...r],则可以对半分成A[p...q]和A[q...r],然后将这有序的两部分Merge,而Merge的过程为Θ(n)

C++ Merge sort(归并排序)

归并排序(merge sort)是一个时间复杂度为O(nlogn)的基于比较的排序算法(comparison based sorting algorithm). 归并排序大多数实现(implementation)都将其实现成了一个stable sort, 所谓的stable sort的意思就是the implementation preserves the input order of equal elements in the sorted order. merge sort 也采用了divi

编程算法 - K路归并排序(k-way merge sort) 代码(C++)

K路归并排序(k-way merge sort) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy K路归并排序作为经典的外部排序算法, 是程序员必须要掌握的. 知识概念参考: <数据结构> 主要思想: 在k个已排序的文件中, 选择第一个值, 采用败者树, 更新二叉树结构, 最终选择最优值. 代码仅供参考, 如最小值用(-1)代替, 最大值用(100)代替. /* * main.cpp * * Created on: 2014年9月11日 *

【 python 学习笔记 -- 数据结构与算法 】归并排序 Merge Sort

[归并排序]这里我们利用递归算法不断地将列表一分为二,base case就是列表中没有元素或者只剩一个元素,因为此时这个子列表必然是正序的:然后再逐步把两个排序完成的子列表合并成一个新的正序列表,直到所有元素排序完毕. [示意图]这是一个从下至上的过程(Bottom-Up) 将列表不断从中间分成两个子列表,直到到达最底部,子列表中只有一个元素 然后,从下至上不断合并两个子列表,将两个子列表的所有元素排序形成一个新的列表. [ implementation of merge sort ] 可以利用

STL 源码剖析 算法 stl_algo.h -- merge sort

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ---------------------------------------------------------------------- 描述:归并排序 思路: 1.将区间对半分割 2.对左.右段分别排序 3.利用inplace_merge将左.右段合并成为一个完整的有序序列 复杂度:O(nlog n) 源码: template<class Bidirection