之前给大家介绍了几个简单的排序。使用递归的方法和迭代的方法实现2路归并,希望对大家有所帮助。归并排序(MergeSort)归并排序是一种必须熟练掌握的排序算法。是面试的高频考点。我们来看看归并排序。原理很简单,大家一下子就明白了。元记酒楼第23届食神大赛开始啦!原主厨想从他旗下排名前四的餐厅中选出一位最优秀的主厨参加厨神大赛。评选规则如下。第一轮PK:各分店选出两名主厨,先进行店内PK,选出店内胜出者。第三次PK:最后剩下的两名获胜者将进行PK,选出最终的获胜者。示意图如下。上面这个食神大赛的例子大家应该都不陌生了。其实我们归并排序的过程和食神选拔赛的过程有些相似。让我们看一下归并排序。merge这个词的意思就是合并的意思,我们数据结构中的定义就是将两个或多个有序列表组合成一个新的有序列表。我们这里说的归并排序,是一种利用归并思想实现的排序方式。归并排序使用了分而治之的思想。顾名思义,分而治之就是把一个大问题分解成几个小的子问题来解决。小问题解决了,大问题也就解决了。分治之后我会写一篇文章来介绍,这里就简单提一下。接下来,我们用一张图来描述归并排序的数据变换,如下图所示。归并排序我们对归并排序的思想有了一个简单的了解。从上面的描述我们可以知道算法的合并过程是比较难实现的。这也是本算法的重点。我们先通过一个视频来看一下合并功能的具体步骤,看完我们的视频大家可以有个大概的了解。视频号视频中的合并步骤你看懂了吗?如果你不这样做,请不要担心。让我们一起分解它。合并过程分为三个步骤。第一步:创建一个额外的大集合来存储合并后的结果,其长度为两个小集合的总和。从视频中也可以看出步骤2:我们从左到右比较两个指针所指向的值,将较小的存入大集合,存完后移动指针,继续比较,直到所有元素一个小集合的存储在大集合中。见下图合并的第三步:当一个smallset的所有元素都放入largeset中时,需要将另一个smallset中剩余的所有元素存入largeset中,如下图.好了,看完视频和图表是不是可以写出大概的思路了?了解了算法原理后,代码写起来就很简单了。让我们看看下面的代码。注意:这里使用的是System.arraycopy(),也可以使用其他方法。这五个参数是,源数组,目标数组,源数组起始索引,目标数组放置起始索引,复制长度classSolution{publicint[]sortArray(int[]nums){mergeSort(nums,0,nums.length-1);returnnums;}publicvoidmergeSort(int[]arr,intleft,intright){if(left>1);mergeSort(arr,left,mid);mergeSort(arr,mid+1,right);merge(arr,left,mid,right);}}//mergepublicvoidmerge(int[]arr,intleft,intmid,intright){//第一步,定义一个新的临时数组int[]temparr=newint[right-left+1];inttemp1=left,temp2=mid+1;intindex=0;//对应第二步,比较每个指针指向的值,小的存入大集while(temp1<=mid&&temp2<=right){if(arr[temp1]<=arr[temp2]){temparr[index++]=arr[temp1++];}else{temparr[index++]=arr[temp2++];}}//对应第三步,将小集合剩余元素存入大集合if(temp1<=mid)System.arraycopy(arr,temp1,temparr,index,mid-temp1+1);if(温度2<=right)System.arraycopy(arr,temp2,temparr,index,right-temp2+1);System.arraycopy(temparr,0,arr,0+left,right-left+1);}}归并排序时间复杂度分析我们需要把两个小集合的长度合并成一个大集合,那么我们需要把待排序序列的长度所有记录都扫描一次所以时间复杂度是O(n)。归并排序将集合逐层分成半组,从完全二叉树的深度可以看出,整个排序过程需要执行logn(向上取整)次,总时间复杂度为O(登录)。另外,归并排序的执行效率与待排序的原始数组的有序程度无关,所以时间复杂度在最好、最坏、平均情况下都是O(nlogn)。虽然归并排序的时间复杂度很稳定,但是它的应用范围没有快速排序那么广泛。这是因为归并排序不是就地排序算法,它的空间复杂度不是O(1)。那么它的空间复杂度是多少呢??归并排序的空间复杂度分析归并排序创建的临时组合会在方法结束时释放。单次归并排序的最大空间为n,所以归并排序的空间复杂度为O(n)。归并排序的稳定性要分析归并排序的稳定性,就要看我们的归并函数了。我们在代码中设置了arr[temp1]<=arr[temp2]。当两个元素相同时,先将arr[temp1]的值放入大集合中,所以两个相同元素的相对位置没有改变,所以归并排序是一种稳定的排序算法。等待还没有结束,不要走。归并排序的递归实现比较普遍,也比较容易理解。我们来看看归并排序的迭代写法。看看他是怎么做到的。下面我们用一段视频来了解一下迭代法的思路视频号是不是可以通过视频大概了解一下呢?下面我们来分析一下视频。迭代实现的归并排序就是将小集合组合成大集合,小集合的大小分别为1,2,4,8,....依次迭代,如下图所示。比如此时smallset的大小为1。这两个小集合是[3]、[1]。然后我们按照合并规则将[3],[1]合并到临时数组中,如第一个视频,小而进,然后排序,然后将临时数组的元素复制到原数组中.实现合并。下面继续合并[4]、[6]。具体步骤是一样的。将所有小集合合并后,小集合的大小变为2,继续执行前面的步骤,如下图所示。此时子集合的大小为2,则为[2,5],[1,3]继续按照上述规则合并到临时数组中,完成排序。这就是迭代法的具体执行过程。我们直接看代码。注意:递归方法的合并函数代码与迭代方法相同。classSolution{publicint[]sortArray(int[]nums){//表示子集合的大小,1,2,4,8,16....intk=1;intlen=nums.length;while(k