归并排序的实现
Posted zhu_free
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了归并排序的实现相关的知识,希望对你有一定的参考价值。
原理
归并的意思是将两个有序的线性表组合成一个新的有序线性表。是基于分治思想的排序算法,它在递归到对数组的l到r的位置之间的数进行排序时,首先根据中间位置 mid=(l+r)/2
分成两半,然后递归分别对左边一半和右边一半进行归并排序,最后对两个已排序好的一半进行合并。(稳定)
其中主要的部分是对两个有序数组的合并,复杂度为O(n)
。以下将合并的部分代码专门写成一个函数
function merge1(arr, left, mid, right)
// 两个数组: arr[left..mid], arr[mid+1..right], 都是有序的
var n = right-left+1; // 两个数组的总长度
var temp = []; // 用来储存元素的临时数组
var l = left, r = mid+1; // 用两个指针分别遍历两个数组
while (l <= mid && r <= right) // 在指针都在数组范围内时
// 比较两个指针指向的元素,把较小的一个放进temp,然后指针+1
if (arr[l] <= arr[r])
temp.push(arr[l++]);
else
temp.push(arr[r++]);
// 循环结束后,肯定有一个数组已经遍历完成,将另一个数组的剩余元素全都加入temp
while (l <= mid)
temp.push(arr[l++]);
while (r <= right)
temp.push(arr[r++]);
// 完成后temp是有序的,这时候把它的元素copy回arr数组的对应位置(left-right)
for (var k = 0; k < n; k++)
arr[left+k] = temp[k]; // copy back
function mergeSort(arr, left, right)
if (left < right)
var mid = Math.floor((left+right) / 2); // 留意js这里需要处理成整数
mergeSort(arr, left, mid);
mergeSort(arr, mid+1, right);
merge2(arr, left, mid, right);
其中,对于merge
部分,遍历两个数组合并成一个,还有一个代码更少但理解起来略微复杂的写法:
function merge2(arr, left, mid, right)
var n = right-left+1;
var temp = [];
var l = left, r = mid+1;
while (l <= mid || r <= right)
if (l <= mid && (r > right || arr[l] <= arr[r]))
temp.push(arr[l++]);
else
temp.push(arr[r++]);
for (var k = 0; k < n; k++)
arr[left+k] = temp[k];
以上是关于归并排序的实现的主要内容,如果未能解决你的问题,请参考以下文章
2022下半年 Acwing 第四篇:AcWing 787. 归并排序