归并排序(每日计划)

60 阅读2分钟

归并排序就有点大事化小的感觉,把一个复杂的问题,拆解成一个很简单问题的集合的过程。

在数组排序中,由于排序的复杂度会随着元素的增多会变得难起来,如果凭借肉眼是很难排好序的,但如果数组中只有两个元素,我们可以很快的排好序。

归并的思路:

[9, 6, 5, 4, 3, 7, 5, 2, 10] 像这样的数组,可以像下面分解,首先把数组一分为二:

[9, 6, 5, 4, 3], [7, 5, 2, 10] 发现还是很难,继续拆分
[9, 6, 5], [4, 3][7, 5],[2, 10] 这样子基本上可以一眼看出来了,但由于是程序,我们把数组的大小都控制 1 个以内,足够简单
[9, 6], [5], [4], [3][7], [5], [2], [10]
[9], [6], [5], [4], [3], [7], [5], [2], [10]

现在已经分解完成了,可以合并了,对于我们来说就很简单了。

1) [9], [6]   					[9, 6]
2) [9, 6], [5]					[9, 6, 5]

3) [4], [3]					[4, 3]

4) [7], [5]					[7, 5]
5) [2], [10]					[10, 2]

6) [9, 6, 5], [4, 3]				[9, 6, 5, 4, 3]

7) [7, 5], [10, 2]				[10, 7, 5, 2]

8) [9, 6, 5, 4, 3], [10, 7, 5, 2]		[10, 9, 7, 6, 5, 5, 4, 3, 2]

全部都是我写完的,因为经过拆分以后就变得很简单了,当然这样的数组即便没有这个也很简单。程序执行的大致就相当于上面,我们先实现拆分的函数。

const mergeSort = (arr) => {
	// 先写结束的条件
    const len = arr.length;
    // 如果数组的个数只有一个,那么就返回就像上面拆分的最后一步的
    if (len < 2) {
    	return arr;
    }
    // 由于 js 这样除会得到小数,所以需要使用这个函数取整,采用向下取整就可以,其实都可以的
    const middle = Math.round(len/2);
    // 拆分数组,拆分成左右两部分
    const leftArr = arr.slice(0, middle);
    const rightArr = arr.slice(middle);
    // 然后把拆分的数组合并并返回,合并的函数 merge 还没实现
    return merge(mergeSort(leftArr), mergeSort(rightArr));
}

现在我们再看数组合并:

// 合并传入的两个数组并排序,我们默认按大到小
const merge = (leftArr, rightArr) => {
	// 由于重点是拆分思想,这里的合并我就简单实现了
    const arr = [...leftArr, ...rightArr]
    // 其实这里使用 “双指针” 法来合并比较好
    return arr.sort((a, b) => b - a)
}

由于我是复习所以一看就明白了,如果你是第一次接触,可以去网上看相关的演示图,更好的理解,下面是可以看各种排序算法的演示图的网址:排序演示