• 归并排序


    归并排序:递归+合并。是经典算法——分治法的典型应用。

    思路:1)将一串数据,首先分成两部分,每个部分分别排序,然后合并成一串数据。2)在1)中,由于每个部分的数据并不是有序的,两个分串就需要再次分别分成两部分,这样的话就有了4个分串。3)一直往下分,直到分到每个部分只有一个数据,而一个数据必定是有序的,因为只有它自己本身。4)在1)~3)的过程中需要用到递归的思想。分到最低层时进行合并,每个分串的数据不断累加,直到变成2个大串,最后合并成一个整串。

    至于有序序列的合并,可以参考<两个有序序列的合并>

    下面用java代码实现。

    /**
         * 将两个有序数列进行合并,从小到大
         * 有序数列分别为:array[firstIndex...middIndex]
         *                   array[middIndex+1...lastIndex]
         * @param array 需要重新整合的数组
         * @param firstIndex 数组中序列1的起始下标
         * @param middIndex 数组中序列1的结束坐标
         * @param lastIndex 数组中序列2的结束坐标
         * @param tempArray 操作过程中临时用于存放数据的数组
         */
        private static void mergeArray(int[] array,int firstIndex,
                        int middIndex,int lastIndex,
                        int[] tempArray) {
            
            //tempArray的坐标
            int tempIndex = 0;
            //序列1的坐标
            int aIndex = firstIndex;
            //序列2的坐标
            int bIndex = middIndex + 1;
            
            //一旦发现序列1或者2中的其中一个的下标已经到了结束坐标
            //需要退出循环,否则会造成内存溢出
            while((aIndex <= middIndex) && (bIndex <= lastIndex)) {
                if(array[aIndex]<array[bIndex]) {
                    tempArray[tempIndex++] = array[aIndex++];
                }
                else {
                    tempArray[tempIndex++] = array[bIndex++];
                }
            }
            
           //如果是序列1的下标还没到结束坐标
            while(aIndex <= middIndex) {
                tempArray[tempIndex++] = array[aIndex++];
            }
            
            //如果是序列2的下标还没有到结束坐标
            while(bIndex <= lastIndex) {
                tempArray[tempIndex++] = array[bIndex++];
            }
            
            //将临时数组tempArray中的数据赋予array
            for(int i = 0; i < tempIndex; i++) {
                array[firstIndex + i] = tempArray[i];
            }
            
        }
        /**
         * 归并排序:递归 && 合并
         * 
         * 首先,只有一个元素的序列必定是有序的
         * 我们可以从一个元素的序列入手,组建成2个元素的有序序列
         * 直到最后组建成N个元素的有序序列
         * 当然,给定了一个N元素的数组后,就是对上面所述的逆过程
         * 
         * @param array 要排序的数组
         * @param firstIndex 数组头
         * @param lastIndex 数组尾
         * @param tempArray 临时数组
         */
        private static void mergeSort(int[] array, int firstIndex, 
                       int lastIndex, int[] tempArray) {
            if(firstIndex < lastIndex) {
                int middIndex = (firstIndex + lastIndex) / 2;
                //左边有序
                mergeSort(array, firstIndex, middIndex, tempArray);
                //右边有序
                mergeSort(array, middIndex + 1, lastIndex, tempArray);
                //将两个有序数列合并
                mergeArray(array, firstIndex, middIndex, lastIndex, tempArray);
            }
            
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] tempArray = new int[10];
            int[] array = {50,10,90,30,70,40,80,60,20};
            mergeSort(array,0,8,tempArray);
            for(int i = 0;i <9; i++) {
                System.out.println(array[i]);
            }
    
        }

     参考文章:http://blog.csdn.net/morewindows/article/details/6678165

  • 相关阅读:
    matrix_last_acm_4
    matrix_last_acm_3
    matrix_last_acm_2
    matrix_last_acm_1
    2015亚洲区北京站网络赛
    poj 1062 昂贵的聘礼 最短路
    2-SAT !!
    hdu 4925
    hdu 4927 Java大数
    poj3687 拓扑排序 还没怎么搞明白 回头再想想
  • 原文地址:https://www.cnblogs.com/hushunfeng/p/3919721.html
Copyright © 2020-2023  润新知