数据结构--归并排序

1 基本思想

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,在使子序列段间有序。若将两个有序表合并称一个有序表,称为二路归并。

2 算法示意图

在这里插入图片描述

3 递归实现归并排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//tmp辅助空间  arr待排序数组
void merge(int* arr, int begin, int mid, int end, int* tmp) {
	//递增
	int begin1 = begin;
	int end1 = mid;
	int begin2 = mid + 1;
	int end2 = end;

	//辅助空间的起始位置
	int idx = begin;
	//合并有序序列
	while (begin1 <= end1 && begin2 <= end2) {
		if (arr[begin1] <= arr[begin2]) {
			tmp[idx] = arr[begin1];
			idx++;
			begin1++;
		}
		else {
			tmp[idx] = arr[begin2];
			idx++;
			begin2;
		}
	}
	//判断是否有未合并的元素
	if (begin1 <= end1)
		memcpy(tmp+idx, arr+begin1, sizeof(int)*(end1 - begin1 + 1));
	if (begin2 <= end2)
		memcpy(tmp + idx, arr + begin2, sizeof(int) * (end2 - begin2 + 1));

	//合并之后的序列拷到原始数组的对应区间
	memcpy(arr + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}

void _mergeSort(int* arr, int begin, int end, int* tmp) {
	if (begin >= end)
		return;
	int mid = begin + (end - begin) / 2;
	//首先合并子序列
	_mergeSort(arr, begin, mid, tmp);
	_mergeSort(arr, mid + 1, end, tmp);

	//合并两个有序的子序列
	merge(arr, begin, mid, end, tmp);
}

void mergeSort(int* arr, int n) {
	//申请辅助空间
	int* tmp = (int*)malloc(sizeof(int) * n);
	_mergeSort(arr, 0, n - 1, tmp);
	free(tmp);
}

4 代码验证

void testMergeSort() {
	int arr[] = { 9 ,1,2,5,7,4,8,6,3,5 };
	int n = sizeof(arr) / sizeof(arr[0]);
	mergeSort(arr, n);
	for (int i = 0; i < n; i++) {
		printf("%d ", arr[i]);
	}
}
int main() {
	testMergeSort();
	return 0;
}

程序运行结果如下:
在这里插入图片描述

5 非递归实现归并排序

void mergeSortNOR(int* arr, int n) {
	//子序列的步长
	int step = 1;
	int* tmp = (int*)malloc(sizeof(int) * n);
	while (step < n) {
		for (int idx = 0; idx < n; idx = idx + 2 * step) {
			int begin = idx;
			int mid = idx + step - 1;
			//判断是否存在第2个序列
			//不存在则直接跳过
			if (mid >= n - 1)
				continue;
			int end = idx + 2 * step - 1;
			//判断第2个序列是否越界
			if (end >= n)
				end = n - 1;
			merge(arr, begin, mid, end, tmp);
		}
		//更新步长
		step = step * 2;
	}
}

6 归并排序特性

  • 归并的缺点在于需要 O ( N ) O(N) O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
  • 时间复杂度: O ( N ∗ l o g N ) O(N*logN) O(NlogN)
  • 空间复杂度: O ( N ) O(N) O(N)
  • 稳定性:稳定
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值