一、分治法简介
分治策略 (divide-and-conquer):将原问题划分成 n 个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。
分治模式在每层都有三个步骤:
- 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。
- 解决这些子问题,递归地求解各子问题。然而,若子问题的规模足够小,则直接求解。
- 合并这些子问题的解成原问题的解。
二、分治法应用——归并排序
归并排序完全依照了分治法的思想:
分解:将个预排列的数分成两个各含n/2个数的子列;
解决:用归并排序法对两个子序列递归地排序;
合并:合并两个已排序的子序列以得到排序结果。
对子序列排序时,其长度为1时递归结束。单个元素被视为是已排好序的。
归并排序的重要步骤就是归并,即将已经排序好的两个子序列合并;
下面引入MERGE过程完成合并:
子数组A1[p…q],A2[q+1…r]合并为A[p…r];
//伪代码
MERGE(A, p, q, r)
n1 = q - p + 1
n2 = r - q
let L[1 .. n1 + 1] and R[1 .. n2 + 1] be new arrays
for i = 1 to n1
L[i] = A[p + i - 1]
for j = 1 to n2
R[j] = A[q + j]
L[n1 + 1] = MAX
R[n2 + 1] = MAX
i = 1
j = 1
for k = p to r
if L[i] <= R[j]
A[k] = L[i]
i = i + 1
else
A[k] = R[j]
j = j + 1
再就是分解子问题的过程,对于数组A[p…r],只有当p>=r(即只有一个元素)时才视为一个已排序的序列;否则就将该数组分解为子数组A1[p…q],A2[q+1…r];
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)
归并排序Java实现:
/*归并排序
*@author WaverlyW
*/
class MergeSort{
private int p,r;
private int[] arry;
MergeSort(int[] arry){
this