归并排序-有递归描述过程

引用:图解排序算法(四)之归并排序

#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
const int N = 10;
void mergeSort ( int *arr, int left, int mid, int right )
{
	int i = left;
	int j = mid + 1;
	int t = 0;
	int *temp = new int[right + 1];
	while ( i <= mid && j <= right ) //小的放进临时数组
	{
		if ( arr[i] < arr[j] )
			temp[t++] = arr[i++];

		else
			temp[t++] = arr[j++];
	}
	while ( i <= mid )
		temp[t++] = arr[i++];
	while ( j <= right )
		temp[t++] = arr[j++];
	t = 0;
	while ( left <= right )//要小于等于因为要赋值rgiht+1次,比如arr[0-2],就是3次
		arr[left++] = temp[t++];
	delete []temp;
}

void sort ( int *arr, int left, int right )
{
	if ( left < right )
	{
		int mid = ( left + right ) / 2;
		sort ( arr, left, mid );
		sort ( arr, mid+1, right );
		mergeSort ( arr, left, mid, right );
	}
}



int main()
{
	srand ( time ( 0 ) );
	int arr[N];
	int i = 0;
	while ( i < N )
	{
		arr[i++] = rand() % 100;

	}

	i = 0;
	cout << "Original:" << endl;
	while ( i < N )
	{
		cout << arr[i++] << " ";
	}
	cout << endl;

	sort ( arr, 0, N - 1 );

	i = 0;
	cout << "Sort:" << endl;
	while ( i < N )
	{
		cout << arr[i++] << " ";
	}

	return 0;
}

(递归的过程)

### 归并排序升序的分治法数学建模过程 归并排序是一种经典的基于分治策略的排序算法,其数学建模过程可以分为以下几个核心部分进行描述: #### 1. 分治策略的分解阶段 在归并排序中,分解阶段的目标是将原始序列不断分割为更小的部分,直到每个部分仅包含一个元素。这一过程可以通过递归实现,每次将当前序列的中间位置作为分割点[^1]。 假设待排序的序列为 $ a[n] = \{a_1, a_2, a_3, ..., a_n\} $,初始时将其视为一个整体。通过递归的方式,将该序列不断划分为左右两个子序列,直到每个子序列只包含一个元素。此时,单个元素的子序列被认为是有序的,因为它们无法进一步比较[^2]。 #### 2. 合并阶段的数学模型 合并阶段是归并排序的核心部分,它涉及将两个已排序的子序列合并为一个更大的有序序列。假设两个子序列分别为 $ A[m] = \{a_1, a_2, ..., a_m\} $ 和 $ B[k] = \{b_1, b_2, ..., b_k\} $,且两者均已按升序排列。目标是将这两个子序列合并为一个新的有序序列 $ C[m+k] $。 具体步骤如下: - 初始化两个指针 $ i $ 和 $ j $,分别指向 $ A[m] $ 和 $ B[k] $ 的起始位置。 - 比较 $ A[i] $ 和 $ B[j] $ 的值,将较小的元素放入结果序列 $ C[] $ 中,并将对应的指针向前移动一位。 - 如果其中一个子序列的所有元素已经处理完毕,则将另一个子序列的剩余部分直接追加到结果序列中[^3]。 #### 3. 时间复杂度分析 归并排序的时间复杂度可以通过递推关系式进行建模。假设排序长度为 $ n $ 的序列所需的时间为 $ T(n) $,则有以下递推关系: $$ T(n) = 2T\left(\frac{n}{2}\right) + O(n) $$ 其中,$ 2T\left(\frac{n}{2}\right) $ 表示对左右两个子序列分别进行排序所需的时间,而 $ O(n) $ 表示合并两个子序列所需的时间。根据主定理,可以得出归并排序的时间复杂度为 $ O(n \log n) $[^4]。 #### 4. 空间复杂度分析 归并排序的空间复杂度主要由辅助数组决定。在合并阶段,需要额外的空间来存储临时的有序序列。因此,归并排序的空间复杂度为 $ O(n) $,其中 $ n $ 是输入序列的长度[^5]。 #### 示例代码实现 以下是归并排序的完整代码实现,展示了分解和合并的具体操作: ```python def merge_sort(arr): if len(arr) <= 1: return arr # 分解阶段 mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) # 合并阶段 return merge(left, right) def merge(left, right): result = [] i = j = 0 # 双指针合并两个有序子序列 while i < len(left) and j < len(right): if left[i] <= right[j]: # 按照升序规则选择较小的元素 result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 # 将剩余的元素加入结果列表 result.extend(left[i:]) result.extend(right[j:]) return result ``` #### 数学建模总结 归并排序通过分治策略实现了高效的排序过程。分解阶段利用递归将问题规模逐步缩小,而合并阶段则通过双指针技术将两个有序子序列高效地合并为一个更大的有序序列。整个过程的时间复杂度为 $ O(n \log n) $,空间复杂度为 $ O(n) $[^6]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值