js 实现归并排序算法

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

递归法求解

javascript 复制代码
const mergeSort = (arr) => {
    const n = arr.length
    if (n <= 1) {
        return arr
    }
    let mid = Math.floor(n / 2)
    const arr1 = arr.slice(0, mid)
    const arr2 = arr.slice(mid, n)
    return merge(mergeSort(arr1), mergeSort(arr2), n)
}

const merge = (arr1, arr2, n) => {
    const mergeArr = new Array(n)
    let idx = 0
    let idx1 = 0
    let idx2 = 0
    while(idx1 < arr1.length && idx2 < arr2.length) {
        if (arr1[idx1] < arr2[idx2]) {
            mergeArr[idx] = arr1[idx1]
            idx1 += 1
        } else {
            mergeArr[idx] = arr2[idx2]
            idx2 += 1
        }
        idx += 1
    }
    if (idx1 < arr1.length) {
        while(idx1 < arr1.length) {
            mergeArr[idx] = arr1[idx1]
            idx1 += 1
            idx += 1
        }
    } else {
        while(idx2 < arr2.length) {
            mergeArr[idx] = arr2[idx2]
            idx2 += 1
            idx += 1
        }
    }
    return mergeArr
}

const arr = [1100,200,500,1600,25,13,685,23651,0,12,35,478,66,5,3,9,8,456,58,68,95,25,12,45,65,8,78,95,68,321,456,122,258,951,864,57,85,95,96,93,92,94,98,25,26,28,29,68,65,62,67,789,752,751,745,6859,3,20,359,215,687,592]
const newarr = mergeSort(arr)
console.log(newarr)

递归法需要新建很多新数组占用存储空间,数据大时比较占内存。

非递归法

gap从小往大逐渐增加,c++的实现方法如下

cpp 复制代码
// 非递归 处理越界版本
void _MergeSort(int* a, int L, int R, int* tmp, int n) {
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)
		{
			int begin1 = i, end1 = begin1 + gap - 1;
			int begin2 = end1 + 1, end2 = begin2 + gap - 1;

			// 处理越界的逻辑
			if (end1 >= n || begin2 >= n) break;
			if(end2 >= n) end2 = n - 1;


			int j = begin1;
			while (begin1 <= end1 && begin2 <= end2) {
				if (a[begin1] < a[begin2]) {
					tmp[j++] = a[begin1++];
				}
				else if (a[begin1] >= a[begin2]) { // 还有一种相等的情况,随便加在一个地方就行
					tmp[j++] = a[begin2++];
				}
			}

			// 当区间没走完,就把剩下的拷贝进数组
			while (begin1 <= end1) {
				tmp[j++] = a[begin1++];
			}
			while (begin2 <= end2) {
				tmp[j++] = a[begin2++];
			}
			memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1)); // 注意不能直接用 begin1 ,begin1 已经加加变化过了
		}
		gap *= 2;
	}
}
相关推荐
hetao173383716 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
Zootopia62617 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
longlongzihan17 小时前
从LeetCode 70. 爬楼梯看动态规划:如何精准推导状态转移方程?
c++·算法·leetcode·动态规划
2601_9603563818 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
h_a_o777oah19 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO919 小时前
指针的算术运算详解
java·数据结构·算法
Coder-magician19 小时前
《代码随想录》刷题打卡day47:并查集-part01
数据结构·算法·图论
垆边人似月.19 小时前
VLAN 资源池(100~200 分档)
数据结构·算法
潼心1412o20 小时前
C++初阶(长期更新)第6讲:类和对象(下)
开发语言·c++·算法
星光开发者20 小时前
基于决策树随机森林算法的小说推荐系统的设计与实现-计算机毕设【课程设计】78485
vue.js·算法·微信小程序·django·php·课程设计·express