排序算法:归并排序

代码演示

#include <stdio.h>
#include <stdlib.h>

//辅助函数: 打印数组
void print_arr(int arr[], int n) {
	int i = 0;
	for (i = 0; i < n; i++) {
		printf("%d ", arr[i]);
	}
	printf("\n");
}

//合并
void merge(int arr[], int tempArr[], int left, int mid, int right) {
	//标记左半区第一个未排序的元素
	int l_pos = left;
	//标记右半区第一个未排序的元素
	int r_pos = mid + 1;
	//临时数组元素下标
	int pos = left;

	//合并
	while (l_pos <= mid && r_pos <= right) {
		if (arr[l_pos] < arr[r_pos])//左半区第一个元素更小
			tempArr[pos++] = arr[l_pos++];
		else//右半区第一个元素更小
			tempArr[pos++] = arr[r_pos++];
	}

	//合并左半区剩余的元素
	while (l_pos <= mid) {
		tempArr[pos++] = arr[l_pos++];
	}

	//合并右半区剩余的元素
	while (r_pos <= right) {
		tempArr[pos++] = arr[r_pos++];
	}

	//把临时数组中合并后的元素复制回原来的数组
	while (left <= right) {
		arr[left] = tempArr[left];
		left++;
	}
}

//归并排序
void msort(int arr[], int tempArr[], int left, int right) {
	//如果只有一个元素,那么就不需要继续划分
	//只有一个元素的区域,本身就是有序的,只需要被归并即可
	if (left < right) {
		//找中间点
		int mid = (left + right) / 2;

		//递归划分左半区
		msort(arr, tempArr, left, mid);

		//递归划分右半区
		msort(arr, tempArr, mid + 1, right);

		//合并已经排序的部分
		merge(arr, tempArr, left, mid, right);
	}

}

//归并排序入口
void merge_sort(int arr[], int n) {
	//分配一个辅助数组
	int *tempArr = (int *)malloc(n * sizeof(int));

	if (tempArr) { //分配成功
		msort(arr, tempArr, 0, n - 1);
		free(tempArr);
	} else {
		printf("error: failed to allocate memory");
	}
}

int main() {
	int arr[] = {9, 5, 2, 7, 12, 4, 3, 1, 11};
	int n = 9;
	print_arr(arr, n);

	merge_sort(arr, n);
	print_arr(arr, n);

	return 0;
}

 算法简介

        归并排序是一种经典的排序算法,它基于分治的思想,将一个待排序的序列逐步划分为较小的子序列,然后通过合并操作将这些子序列有序地合并成一个有序序列。

        下面是归并排序的基本步骤:

  1. 分割:将待排序序列不断二分,直到每个子序列只包含一个元素或为空。
  2. 合并:将相邻的子序列两两合并,合并过程中保持元素的有序性。具体操作是比较两个子序列的首元素,将较小的元素放入新的序列,并将该子序列的指针向后移动,重复这个过程直到某个子序列为空,然后将另一个非空子序列的剩余部分直接拷贝到新序列中。
  3. 重复合并操作,直到所有子序列都合并成一个完整的有序序列。

        归并排序的关键在于合并操作,它需要额外的空间来存储合并过程中产生的临时序列。因此,在实际应用中,归并排序的空间复杂度为O(n),其中n为待排序序列的长度。时间复杂度为O(nlogn),这是由于每次合并操作需要O(n)的时间,而分割操作需要进行logn次。

        归并排序是一种稳定的排序算法,适用于各种数据规模和类型的排序任务。它的主要优点是在最坏情况下仍具有较好的性能,并且可以有效地处理大型数据集。然而,归并排序需要额外的空间来存储临时序列,这可能在内存受限的环境下造成问题。

        总之,归并排序是一种高效、稳定的排序算法,通过分治和合并操作实现将待排序序列有序化。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值