排序算法——归并排序

归并排序是一种采用分治法的排序算法,通过不断将子序列划分至单元素,然后逐步合并成有序序列。其时间复杂度为O(nlogn)。本文介绍了归并排序的伪代码、示例及C++实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序

其基本思想是:对于两个有序序列(集合),将其融合在一起得到一个新的有序序列,又被称为二路归并

因此,归并排序的过程就是:首先将一个待排序列不断划分,划分为原来的一半,直至子序列只有一个元素为止,此时,每一个子序列只有一个元素,也就是每个子序列都是有序的。这个过程被称为。再将子序列对应融合,按照一定的大小顺序合并在一起,最终得到有序序列,这个过程被称为

归并排序是分治法的经典问题。
归并排序算法的时间复杂度为O(nlogn):分的过程为logn,合的过程为n

伪代码

MERGE(A,p,q,r)
    n1=q-p+1;
    n2=r-q;
    create new arrays L[n1+1] and R[n2+1]
    for i=0 to n1-1
        L[i]=A[p+i]
    for j=0 to n2-1
        R[j]=A[q+1+j]
    L[n1]=1000//假设1000是无穷大
    R[n2]=1000
    i=j=0
    for k=p to r
        if(L[i]<=R[j])
            A[k]=L[i]
            i=i+1
        else
            A[k]=R[j]
            j=j+1
            
MERGE_SORT(A,p,r)
    if p<r
        q=floor((p+r)/2)
        MERGE_SORT(A,p,q)
        MERGE_SORT(A,q+1,r)
        MERGE(A,p,q,r)

伪代码来源于https://blog.youkuaiyun.com/feierxiaoyezi/article/details/79998060

若存在序列:{7, 50, 1, 4, 32, 7, 9, 5, 25, 6},使用归并排序进行排序
(“|”表示划分)
7 50 1 4 32 7 9 5 25 6
7 50 1 4 32 | 7 9 5 25 6
7 50 | 1 4 32 | 7 9 | 5 25 6
7 | 50 | 1 4 32 | 7 9 | 5 25 6
7 | 50 | 1 | 4 32 | 7 | 9 | 5 | 25 6
7 | 50 | 1 | 4 | 32 | 7 | 9 | 5 | 25 | 6 ——不断划分直至每个子序列只有一个元素为止

7 50 | 1 4 | 7 32 | 5 9 | 6 25 ——两两合并
1 4 7 50 | 5 7 9 32 | 6 25(*具体演示如何实现该步归并)
1 4 5 7 7 9 32 50 | 6 25
1 4 5 6 7 7 9 25 32 50

对此步进行归并具体过程
(建立一个新的空序列作为排序序列,长度为两个待排序列长度之和)
(加粗表示有序序列,标记表示指针指向)
(空) 1 4 7 50 | 5 7 9 32 ——1<5,放入1
1 4 7 50 | 5 7 9 32 ——4<5,放入4
1 4 7 50 | 5 7 9 32 ——5<7,放入5
1 4 5 7 50 | 7 9 32 ——7=7,放入7(左)
1 4 5 7 50 | 7 9 32 ——7<50,放入7
1 4 5 7 7 50 | 9 32 ——9<50,放入9
1 4 5 7 7 9 50 | 32——32<50,放入32
1 4 5 7 7 9 32 50 ——放入50
1 4 5 7 7 9 32 50
即完成该步归并

在这里插入图片描述

gif制作来源于VisuAlgo https://visualgo.net/zh/sorting

代码

#include <iostream>

#define N 10
using namespace std; 

//归并排序
void merge(int a[], int start1, int end1, int start2, int end2) {
	int i = start1, j = start2;
	int n = (end1 - start1 + 1) + (end2 - start2 + 1);
	vector<int> temp(n);
	int k = 0;
	while (i <= end1 && j <= end2) {
		if (a[i] < a[j])
			temp[k++] = a[i++];
		else
			temp[k++] = a[j++];
	}
	while (i <= end1)
		temp[k++] = a[i++];
	while (j <= end2)
		temp[k++] = a[j++];
	for (int i = 0; i < n; i++)
		a[start1 + i] = temp[i];
}

void MergeSort(int a[], int start, int end) {
	if (start < end) {
		int mid = (start + end) >> 1;
		MergeSort(a, start, mid);
		MergeSort(a, mid + 1, end);
		merge(a, start, mid, mid + 1, end);
	}
}


int main() {
	int a[N] = { 7, 50, 1, 4, 32, 7, 9, 5, 25, 6 };
	int length = sizeof(a) / sizeof(a[0]);
	
	MergeSort(a, 0, length - 1);								//归并排序

	for (int i = 0; i < N; i++)
		cout << a[i] << " ";
	cout << endl;

	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值