基础:归并排序

简介

归并排序属于一种分治法,简单来说就是将一个大问题分解成若干类似大问题的子问题,然后分别解决,最后进行合并。

一般的分治法分为如下步骤:
1、分解:把一个问题分解成若干更小的类似的子问题
2、解决:递归解决子问题。当子问题足够小时,按照基础情况求解
3、合并:把子问题的解合并成原问题的解

那么将分治法应用于排序中,步骤如下:
若将一个含有n个元素的数组进行排序
1、分解:一个大问题是从1到n进行排序,那么我们将其分解,选取其中一段,从p到r进行排序。我们找到p与r的中点,反复分解。
2、解决:对p到q位置的数字进行上述递归排序,从q+1到r同理。当少于两个数字需要排序时,就会产生基础情况,因为一个数字显然是不用排序的。
3、合并:对从p到q的数列和q+1到r的数列进行合并。

代码与实操

经过上述分析,我们需要两个函数:分解函数与合并函数

分解

    if (start < end) {//如果start>= end 那这段数组至多有一个元素,那么无需排序
        int mid = (start + end) / 2;
        Mergesort (origin,start,mid);
        Mergesort (origin,mid + 1,end);
        Merge (origin,start,mid,end);
      
    }
}

合并

首先提供一下合并思路:
我们有一个数列a[p~r],我们将其分为两部分x[p~mid]y[mid+1~r]
ij分别取pmid+1
kpr依次取值
x[i] <= y[j]
a[k] = x[i],且i++
代码如下:

    int fir[10001] = {INT_MAX };
    int sec[10001] = {INT_MAX };
    for (int i = start; i <= mid; i++) {
        fir[i] = origin[i];
    }
    for (int i = mid + 1; i <= end; i++) {
        sec[i] = origin[i];
    }

    int n1 = start;
    int n2 = mid + 1;
    for (int k = start; k <= end; k++) {
        if ((n1<=mid&&fir[n1] <= sec[n2])||(n2>end)) {//这里的判定非常重要,要考虑到两边取完数的情况
            origin[k] = fir[n1];
            n1++;
        }
        else {
            origin[k] = sec[n2];
            n2++;
        }
    }
}

代码

#include <bits/stdc++.h>
using namespace std;
int a[1000001] = { };
int ans[10000001] = { };
int left = 0, right = 0;
int n = 0;
void Merge (int origin[],int start,int mid,int end) {
    int fir[10001] = {INT_MAX };
    int sec[10001] = {INT_MAX };
    for (int i = start; i <= mid; i++) {
        fir[i] = origin[i];
    }
    for (int i = mid + 1; i <= end; i++) {
        sec[i] = origin[i];
    }

    int n1 = start;
    int n2 = mid + 1;
    for (int k = start; k <= end; k++) {
        if ((n1<=mid&&fir[n1] <= sec[n2])||(n2>end)) {
            origin[k] = fir[n1];
            n1++;
        }
        else {
            origin[k] = sec[n2];
            n2++;
        }
    }
}
void Mergesort (int origin[],int start,int end){
    if (start < end) {
        int mid = (start + end) / 2;
        Mergesort (origin,start,mid);
        Mergesort (origin,mid + 1,end);
        Merge (origin,start,mid,end);
        
    }
}
int main () {
    scanf ("%d/n" ,&n);
    for (int i = 1;i <= n; i++) {
        cin >> a[i];
    }
    Mergesort(a,1,n);
    for (int i = 1;i <= n; i++) {
        printf ("%d " ,a[i]);
    }
    return 0;
}
posted @   24Kmagic  阅读(10)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示