分治與遞迴
分治法的設計思想是,將乙個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。
對這k個子問題分別求解。如果子問題的規模仍然不夠小,則再劃分為k個子問題,如此遞迴的進行下去,直到問題規模足夠小,很容易求出其解為止。
將求出的小規模的問題的解合併為乙個更大規模的問題的解,自底向上逐步求出原來問題的解。
【程式1】乙個簡單例子
在乙個整數組a[1...n]中,同時尋找最大值和最小值
【方法一】順序掃瞄法
min=a[1];
max=a[1];
掃瞄陣列,對i從2到n做:
如果a[i]max,則max = a[i];
返回max,min的值
【方法二】分治法
基本思想:
(1)劃分:將陣列分割成兩半
(2)治理:在每一半中找到最大值和最小值。
(3)合併:返回兩個最大值中的最大值和兩個最小值中的最小值。
minmax(int left, int right)
int main()
【程式3】二分查詢
給定n個從小到大排列的整數,查詢其中是否存在x,若存在;返回位置,否則返回0。
樣例輸入:
512 5 6 87 20
87樣例輸出:
4
int binaryserach(int left,int right)
return -1;
}
【程式4】歸併排序
對a[1...n]排序。
樣例輸入:
512 5 6 87 20
樣例輸出:
5 6 12 20 87
【分析】我們先看乙個簡單的問題:
合併兩個已排序的表
將兩個已排序的順序表合併成乙個有序表。順序比較兩者的相應元素,小者移入另一表中,反覆如此,直至其中任一表都移入另一表為止。
如下圖所示:
後面的比較過程採用相同的方法,就不一一枚舉。
歸併排序的過程(分治策略):
(1)劃分:將a[1...n]分為a[1...n/2] 和 a[n/2+1...n]兩部分;
(2)治理:分別對a[1...n/2] 和a[n/2+1...n]排序
(3)組合:將兩個有序子串行合併為乙個有序序列
歸併排序c++模板:
#includeusing namespace std;
int a[5000],b[5000];
void merge(int l1,int r1,int l2,int r2)else
k++;
} for(t=i;t<=r1;t++)
for(t=j;t<=r2;t++)
for(t=l1;t<=r2;t++) a[t]=b[t]; //再把合併後的陣列賦給a
}void mergesort(int left,int right)
遞迴與分治
一 1 求階乘 int factorial int n 2 fibonacci函式 int fibonacci int n 3 全排列 1 字串的全排列 主函式見 2 int permutation char a,int k,int m permutation arr,0,n 1 return 0 ...
遞迴與分治
fibonacci數列 無窮數列1,1,2,3,5,8,13,21,34,55,稱為fibonacci數列。它可以遞迴地定義為 第n個fibonacci數可遞迴地計算如下 int fibonacci int n 編寫完整的主函式,分別記錄利用上述遞迴函式求第47,48,49,50,51,52個fib...
分治回溯 遞迴與分治
程式呼叫自身的程式設計技巧稱為遞迴 public static void show 它通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大地減少了程式的 量。一般來說,遞迴需要有邊界條件 遞迴前進段和遞迴返回段。...