首先介绍一下归并排序:
归并排序是采用归并的思路进行排序,该算法采用经典的分治策略(把一个大问题分解为若干个小的问题进而求解的过程)。字面上看起来还是很抽象的,接下来给出归并排序的整个示意图:
解释:这里的“分”和“治"的过程都是递归进行,实际上”分“过程不做任何操作,在”分“的过程中持续压栈,直到最后序列中的元素只有一个。然后再进行”治“也就是归并操作。这个部分需要在代码片段中认真体会。
前面说到”分“只是在逻辑上分裂序列,实际不做任何操作。重点就在于”治“也就是归并操作。那么,如何把分裂的元素归并成一个有序的序列呢?这里需要定义一个临时的数组temp[],用来存放排好序的序列。所以如何放置元素到临时数组temp[]又是一个问题。
这里的放置原则是:由于两个序列都已经有序,我们只需要从这两个序列的低位轮番比较,将比较结果小的值放置到temp[]临时数组中,然后继续拿出该值所在序列中的下一个元素比较,直到某个序列中没有元素后,再将另一方的剩余元素依次放置再temp[]临时数组后面即可。此时临时数组里面存放的序列是两个序列的有序合并,最后将临时数组拷贝给原数组即可。
以上这个过程不难体会。
经过”分“和”治“的阶段,待排序列就已经成了有序序列。到此还不理解没关系,接下来给出完整代码,因为一段正确的代码是具有唯一逻辑性的,这段代码重点除了理解递归的过程之外还要理解temp[]拷贝的过程(它不是一次性拷贝的,而是每归并一次就拷贝一次)。
/**
* 分裂+归并
* @param arr 待排序数组
* @param left 左序列起始下标
* @param right 右序列起始下标
* @param temp 临时数组
*/
public static void mergerSort(int[] arr,int left,int right,int[] temp){
if (left <