分治法:
将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
(1)可行性:如果原问题可分割成k个子问题(1<k<=n),且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么分治法就是可行的。
(2)分治法与递归的关系:由于分治法产生的子问题往往是原问题的较小模式,这就为递归方法的使用提供了方便,可以使子问题与原问题类型一致而其规模不断缩小,从而引出递归算法。
递归:
直接或间接地调用自身的算法称为递归算法
分治法的基本步骤:
分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题合并:将各个子问题的解合并为原问题的解。
伪代码:
begin {开始}
if ①问题不可分 then ②返回问题解
else begin
③从原问题中划出含一半运算对象的子问题1;
④递归调用分治法过程,求出解1;
⑤从原问题中划出含另一半运算对象的子问题2;
⑥递归调用分治法过程,求出解2;
⑦将解1、解2组合成整修问题的解;
end;
end; {结束}
可用分治法解决的问题:
1.归并排序:
package com.lyj.sort;
public class MergeSort {
public static void main(String[] args) {
int[] a = { 1, 15, 24, 26, 58, 45, 14, 15, 14, 74 };
mergesort(a, 0, a.length - 1);
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
public static void mergesort(int a[], int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
mergesort(a, low, mid);
mergesort(a, mid + 1, high);
merge(a, low, high);
}
}
public static void merge(int[] a, int low, int high) {
int mid = (low + high) / 2;
int[] b = new int[high - low + 1];
int s = low;
int t = mid + 1;
int k = 0;
while (s <= mid && t <= high) {
if (a[s] <= a[t])
b[k++] = a[s++];
else
b[k++] = a[t++];
}
while (s <= mid)
b[k++] = a[s++];
while (t <= high)
b[k++] = a[t++];
for (int i = 0; i < b.length; i++) {
a[low + i] = b[i];
}
}
}