【分治算法】归并排序,快速排序和汉诺塔

这篇博客介绍了分治算法的三个经典实例:归并排序、快速排序和汉诺塔问题。归并排序通过拆分和合并保持有序的子数组实现排序;快速排序则是通过选取基准元素,将数组分为两部分,再递归地排序;汉诺塔问题则展示了递归在解决复杂问题中的应用。文章详细解析了每个算法的思路、步骤和源代码,适合学习分治算法的读者参考。

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

1介绍

分治算法已经是本人所写的常用算法系列的第三个了,可能只会写这一节,对比动态规划与贪心算法我们来认识一下分治算法。
从思路上来看:
(1)动态规划:多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。每一个阶段的最优解是基于前一个阶段的最优解。
(2)贪心算法:选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。不是对所有问题都能得到整体最优解。
(3)分治算法:将一个大规模的问题分解成n个容易解决的小问题,当小问题被解决时,最终的问题也被解决了。
乍一看,似乎区别不大。
从代码结构上来看(不绝对):
(1) 动态规划:通常为两层for循环嵌套;
(2) 贪心算法:通常先进行排序,后进行选择;
(3) 分治算法:通常为递归;

2归并排序

2.1问题

问题:使用归并排序以下数字:8,7,4,2,2,1,19,23,5,3

2.2解析

按照分治算法的思想,题中数组Array有10个数字,不太方便操作,应该将其分解为若干个容易解决的子问题。假设现在排序的是包含1个数字的数组Array,是不是就非常容易了(一个数字都不用排序)。
现将数组Array分解为10个数组,每个数组只含有1个数字,这就是归并排序中“归”的过程。

数组只含有1个数字,可见该数组已经有序了。然后将两个有序的数组合并起来,当然合并的时候也要确保合并之后的数组也是有序的。这就是归并排序中“并”的过程。


归并排序的处理过程:
(1)“归”:拆分为只含有一个数字的数组;

void SplitSort(int first,int last,int a[],int temp[]){
	if (last>first){
		int mid = (first + last) / 2;
		SplitSort(first,mid,a,temp);
		SplitSort(mid+1,last,a,temp);
		MergeSort(first,last,mid,a,temp);
	}
}

(2)“并”:将两个有序的数组合并成一个有序的数组;

void MergeSort(int first,int last,int mid,int a[],int temp[]){
	int i = first, j = mid + 1;
	int m = mid, n = last;
	int k = 0;

	while (i <= m && j <= n)
	{
		if (a[i] <= a[j])
			temp[k++] = a[i++];
		else
			temp[k++] = a[j++];
	}

	while (i <= m)
		temp[k++] = a[i++];

	while (j <= n)
		temp[k++] = a[j++];

	for (i = 0; i < k; i++)
		a[first + i] = temp[i];
}

本题完整源代码:

#include<iostre
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值