zoukankan      html  css  js  c++  java
  • Merge Sort

    package com.exuan.sort;

    public class MergeSort {

        /*
         * Conceptually, a merge sort works as follows
         * 1. If the list is of length 0 or 1, then it is already sorted. Otherwise:
         * 2. Divide the unsorted list into two sublists of about half the size.
         * 3. Sort each sublist recursively by re-applying the merge sort.
         * 4. Merge the two sublists back into one sorted list.
         */
        
        public static void main(String[] args)
        {
            int[] data = {49,38,65,97,76,13,27,49,55,4};
            display(data);
            mergeSort1(data, 0, data.length - 1);
            //mergeSort2(data);
            display(data);
        }
    /*
     * ------------------------------------------------------------------
     * 1. recursive
     */
        
        static void mergeData1(int array[], int p, int q, int r)
        {
            int i,k;
            int begin1, end1, begin2, end2;
            int[] temp = new int[r - p + 1];
            begin1= p;
            end1 = q;
            begin2 = q+1;
            end2 = r;
            k = 0;
            while((begin1 <= end1)&&( begin2 <= end2))
            {
                if(array[begin1] < array[begin2])
                {
                    temp[k] = array[begin1];
                    begin1++;
                }
                else
                {
                    temp[k] = array[begin2];
                    begin2++;
                }
                k++;
            }
            while(begin1<=end1)
            {
                temp[k++] = array[begin1++];
            }
            while(begin2<=end2)
            {
                temp[k++] = array[begin2++];
            }
            for (i = 0; i <= (r - p); i++)
            {
                array[p+i] = temp[i];
            }
        }
        
        static void mergeSort1(int array[], int first, int last)
        {
            int mid = 0;
            if(first < last)
            {
                mid = (first+last)/2;
                mergeSort1(array, first, mid);
                mergeSort1(array, mid + 1,last);
                mergeData1(array, first, mid, last);
            }
        }

    /*
    * 1. recursive
    * ------------------------------------------------------------------
    */

    /*
    * ------------------------------------------------------------------
    * 2. not recursive
    */    
        /*
         * first is the start of the first sub sequence,
         * second is the start of the second sub sequence,
         * left_width is the length of the sub sequence
         */
        private static void mergeData2(int[] data, int first, int second, int left_width)
        {
            int right_width;
            /*
             * if the length of second sub sequence is less than the first,
             * for example {13,27,38,49,49,65,76,97},{4,55}
             * then right_width is the actual length
             */
            if(second + left_width - 1 >= data.length - 1)
            {
                right_width = data.length-second;
            }
            else
            {
                /*
                 * the length of second sub sequence is equal to the first
                 * for example {38,49,65,97},{13,27,49,76}
                 * right_width = left_width = 4
                 */
                right_width = left_width;
            }
            /*
             * create a temp array that can store the sort result of the two sub sequences,
             * so its size is 'left_width+right_width'
             */
            int[] temp = new int[left_width+right_width];
            int i = 0;
            int j = 0;
            /*
             * i loop in the first sub sequence, j loop in the second sub sequence,
             * we now start to merge the two sub sequences,
             * this 'while' loop end when we reach one of the sub sequence' end
             */
            while(i <= left_width - 1 && j <= right_width - 1)
            {
                /*
                 * if data in first sub sequence is less,
                 * we store it to the temp array,
                 * increase i
                 */
                if(data[first+i] <= data[second+j])
                {
                    temp[i+j] = data[first+i];
                    i++;
                }
                else
                {
                    /*
                     * if data in second sub sequence is less,
                     * we store it to the temp array,
                     * increase j
                     */
                    temp[i+j] = data[second+j];
                    j++;
                }
            }
            
            /*
             * we reach the end of the second sub sequence,
             * which means the the data in second sub sequence is less than some of the first,
             * we then move the unsorted data in the first sub to right
             */
            if(j == right_width)
            {
                for(int t = 0; t < left_width - i; t++)
                {
                    data[first + i + j + t] = data[first + i + t];
                }
            }
            
            /*
             * copy the temp sorted data to our array
             */
            for(int t = 0; t < i + j; t++)
            {
                data[first + t] = temp[t];
            }
        }
        
        private static void mergeSort2(int[] data)
        {
            int step = 1;
            /*
             * we increase the step from 1 to data length - 1,
             * divide the original sequence into several sub sequences,
             * then loop to sort each sub sequence
             */
            while(step < data.length)
            {
                /*
                 * first {49,38},{65,97},{76,13},{27,49},{55,4} to {38,49},{65,97},{13,76},{27,49},{4,55}
                 * the for loop will do merge each sub sequence,
                 * then {38,49,65,97},{13,76,27,49},{4,55} to {38,49,65,97},{13,27,49,76},{4,55}
                 * then {38,49,65,97,13,27,49,76},{4,55} to {13,27,38,49,49,65,76,97},{4,55}
                 * then {13,27,38,49,49,65,76,97,4,55} to {4,13,27,38,49,49,55,65,76,97}
                 */
                for(int i = 0; i <= data.length - step - 1; i += 2 * step)
                {
                    mergeData2(data, i, i + step, step);
                }
                step *= 2;
            }
        }

    /*
    * 2. not recursive
    * ------------------------------------------------------------------
    */    
        
        private static void display(int[] data)
        {
            for(int i = 0; i < data.length; i++)
            {
                System.out.print(data[i]);
                if(i != data.length - 1)
                {
                    System.out.print(",");
                }
            }
            System.out.println();
        }
        
    }

  • 相关阅读:
    关于SQL Server 2005 SP2中提供的Vardecimal存储格式
    .NET平台网络编程之最佳实践 【转载】
    如果类型转换无可避免,那么应该尽可能用as运算符,而不是强制转换
    ArraySegment 的使用 【转载】
    如果不写Order By子句,会怎么样
    ToString 的几个思考
    尽量用属性(Property),而不是字段(Field)
    如何设置SQL Server服务器上面的CPU占用过高的警报
    SQL Server 2008 Replication and Filestream, are both supported together?【转载】
    Microsoft Sync Framework
  • 原文地址:https://www.cnblogs.com/jayceli/p/2428612.html
Copyright © 2011-2022 走看看