分治法 - 合并算法设计
分治法 - 合并算法设计
何为分治法?
分治策略:将圆问题划分为n个规模较小而结构与圆问题相似的子问题;地鬼地解决这些子问题。然后合并结果,即得到原问题的解。
分治模式每一层的递归上都有三个步骤:
分解:将原问题分解为一系列子问题;
解决:递归地解决各子问题。若子问题较小,则直接求解。
合并:将子问题的解合并为原问题的解。
一. 问题描述:
由n个数组成的序列a1,a2, …, an; 对上述序列采用合并排序算法进行排序。
二. 算法分析
合并排序算法完全依照了上述模式,步骤如下:
分解:将n个元素分成各含n/2个元素的子序列;
解决:用合并排序算法对两个子序列递归地排序;
合并:合并两个以排序的子序列的以得到原序列的排序结果。
在对子序列排序时,长度为1时递归结束,单个元素被视为已排好序的。
合并排序算法的关键步骤在于合并两个已经排好序的子序列。为做合并,引入辅助过程merge(A, p, q, r),其中A是数组,p, q, r是数组下标满足p<=q<r, A[p, q]和A[p+1, r]是已经排号序的数组。merge(A, p, q, r)就是将A[p, q]和A[q+1, r]合并为数组A[p, r]。
以扑克牌为例,现有两堆扑克牌,都是已经排好序的,最小的放在最上面。现在我们希望把两堆扑克牌合并为排好序的一堆。基本步骤如下,从两堆中选取较小的一张,将其取出,面朝下放在输出堆中,直至某一堆完全为空为止(或定义一个哨兵牌,即直至某一堆出现哨兵牌为止),然后把另一输入堆余下的牌全部放入输出堆上。因为之多n次比较,所以时间复杂度为O(n)。
Merge(A, p, q, r) { 定义m1=q-p+1,m2=r-q; 创建序列L(1,m1),R(1, m2); /* 定义序列L(1, m) ,R(1, m2)*/ for i = 1~m1 L(i) = A(p+i-1) for j = 1~m1 R(j) = A(p+j) 再定义哨兵L(m1+1)= 无穷大;R(m2+1) = 无穷大; 定义i=1; j=1; for k = p~r if L(i) <= R(j) then A[k] = L(i);i=i+1; else then A[k] = R(j);j=j+1; }
合并排序的算法
Merge_sort(A, p, r) { if (p<r) { q={小于或等于(p+r)/2的最大整数}; Merge_sort(A, p, q); Merge_sort(A, q+1, r); Merge (A, p, q, r); } }
三. 效率分析
设T(n)表示一个规模为n的问题的运行时间。如果问题规模足够小,如n<=c(一常数),则其直接解的为常量,设为O(1)。
假设把问题分解为a个子问题;每一个子问题的规模是原问题的n/b,并假设分解该问题和合并该问题的时间为D(n)和C(n),从而的效率模型为T(n) = aT(n/b)+ D(n)+C(n),可由master theory知,时间复杂度T(n) =O(nlgn);
四. C实现
/** * merge - 将已经排好序的array[low,mid]与array[mid+1,high] * 合并为一个array[low,high],并且也是排好序的 * Param.: * @array: 数组 * @low:起始脚标 * @mid:中间脚标 * @high:终止脚标 * Return: * 无 */ void merge(intarray[], int low, int high, int mid) { int i, j, k, tmp; i = low; j = mid + 1; while (i < j && j <= high) { if (array[i] > array[j]) { tmp = array[j]; for (k = j; k > i; k--) array[k] = array[k - 1]; array[i] = tmp; j++; } i++; } } /** * merge_sort - 合并排序,排序后序列放入源数组 * Param.: * @array: 数组 * @low:起始脚标 * @high:终止脚标 * Return: * 无 */ void merge_sort(intarray[], int low, int high) { int mid; if (low >= high) return; mid = (low + high) / 2; merge_sort(array, low, mid); merge_sort(array, mid + 1, high); merge(array, low, high, mid); }
posted on 2012-03-08 21:50 YoungerChina 阅读(595) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人