排序算法之归并排序(Java 版本)

news/2024/5/17 20:01:34 标签: 归并排序, 分治策略, 算法, 递归, JAVA

排序算法归并排序

归并排序分治策略的应用之一,分而治之。
时间复杂度为 O(n log n)
归并排序的思想是:将队列拆分为子队列直到不可分,再将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

核心

归并排序的核心是分治思想递归实现

  • 分治策略:将原问题分解为几个规模较小但类似于原问题的子问题,递归求解这些子问题,然后合并子问题的解来建立原问题的解。

无图无真相,归并排序流程图(盗用百度百科?)
在这里插入图片描述

算法分析

  • 先将队列递归分解(采用中点分解),直到队列中的元素个数为1
  • 分解队列通过计算队列中点,分为左队列(low,mid)和右队列(mid+1,high)
  • 当将原队列拆分为最小队列后(队列中只有一个元素),子队列有序
  • 将两个有序队列合并为一个有序队列,代码中的mergeArray方法

代码实现

注释比较详细,不做赘述


    /**
     * 
     * @param array 排序数组
     * @param start 开始位置
     * @param end 结束位置
     */
    private void mergeSort(int[] array, int start, int end) {
        if (start < end) {//当数组中的元素不可分时,停止分解
            int mid = (start + end) / 2;//计算中间坐标
            mergeSort(array, start, mid);//递归分解数组
            mergeSort(array, mid + 1, end);//递归分解数组
            //合并数组,合并后为有序数组
            //因为前面为递归调用,所以可以保证第一次调用此方法时,子数组长度为1
            mergeArray(array, start, mid, end);
        }
    }
    
    private void mergeArray(int[] array, int start, int mid, int end) {
        int[] left = new int[mid - start + 1 //存放数据长度
                + 1];//预留安全守卫
        int[] right = new int[end - mid//存放数据长度
                + 1];//预留安全守卫
        System.arraycopy(array, start, left, 0, left.length - 1);
        System.arraycopy(array, mid + 1, right, 0, right.length - 1);

        left[left.length - 1] = SAFE_GUARD;
        right[right.length - 1] = SAFE_GUARD;
        
        int l = 0, r = 0;

        for (int i = start; i <= end; i++) {
            if (right[r] == SAFE_GUARD) {
                array[i] = left[l];
            }
            if (left[l] == SAFE_GUARD) {
                array[i] = right[r];
            }
            if (left[l] <= right[r]) {
                array[i] = left[l];
                l++;
            } else {
                array[i] = right[r];
                r++;
            }
        }
    }

结语

个人认为归并排序重要的是分治思想。JDK7引入了ForkJoinPool也是分治策略的应用。既然如此,需要好好了解下分治策略啦!
算法导论》第二天,加油!下一篇分治策略


http://www.niftyadmin.cn/n/1568392.html

相关文章

Android监听apk安装、卸载、替换的事件类型

Android监听apk安装、卸载、替换的事件类型如下&#xff1a; android.intent.action.PACKAGE_ADDED android.intent.action.PACKAGE_REMOVED android.intent.action.PACKAGE_REPLACED

算法之分治策略与应用

归并排序中我们利用了分治策略&#xff0c;在分治策略中&#xff0c;我们递归求解一个问题&#xff0c;在每层递归中应用如下三个步骤&#xff1a; 分解&#xff1a;将问题划分为一些子问题&#xff0c;子问题的形式与原问题一样&#xff0c;只是规模更小。解决&#xff1a;递归…

android service介绍

很简单一个例子&#xff1a; Android开发中&#xff0c;当需要创建在后台运行的程序的时候&#xff0c;就要使用到Service。Service 可以分为有无限生命和有限生命两种。特别需要注意的是Service跟Activities是不同的&#xff08;简单来说可以理解为后台与前台的区别&#xff…

排序算法之堆排序(Java 版本)

堆排序&#xff0c;使用一种称为堆的数据结构来进行信息管理。堆不仅用在堆排序中&#xff0c;它还可以构造一个有效的优先队列。时间复杂度O(nlogn) 堆 &#xff08;二叉&#xff09;堆是一个数组&#xff0c;可以被看成一个近似的完全二叉树。书上的每个节点对应数组中的一个…

读取文件指定行

/** * 读取文件指定行。 */public class ReadSelectedLine {// 读取文件指定行。 static void readAppointedLineNumber(File sourceFile, int lineNumber) throws IOException {FileReader in new FileReader(sourceFile);LineNumberReader reader new LineNumberRe…

排序算法之快速排序(Java 版本)

快速排序是一种最坏情况时间复杂度为 o(n^2)的算法。虽然最坏情况时间复杂度很差&#xff0c;但是快速排序通常是实际排序应用中最好的选择&#xff0c;因为它的平均性能非常好&#xff1a;它的期望时间排序复杂度是o(nlgn) 描述 与归并排序一样&#xff0c;快速排序算法也使用…

android adb push 和 adb install的区别

..platform\system\core\adb\commandline.c中adb push的实现 if(!strcmp(argv[0], "push")) { if(argc ! 3) return usage(); return do_sync_push(argv[1], argv[2], 0 /* no verify APK */); } 同样的文件中的函数install_app也实现了adb install实现&#xff1a; …

排序算法之计数排序(Java 版本)

计数排序是一个非基于比较的排序算法。它的优势在于在对一定范围内的整数排序时&#xff0c;它的复杂度为Ο(nk)&#xff08;其中k是整数的范围&#xff09;&#xff0c;快于任何比较排序算法。当然这是一种牺牲空间换取时间的算法。 基本思想 计数排序的基本思想是&#xff1a…