“C# :使用遞歸尋找一維整型數組中的最大值”
傳說中的入門算法。首先我們用簡單的for循環語句,遍歷一遍數組就可以找出它的最大值:
1 public class Test { 2 public static void Main(){ 3 int[] array = new int[] { 2,4,5,6,23,24,21,66,21}; 4 int max = array[0]; 5 //通過使用for循環求出array數組的最大值
6 for (int i = 0; i < array.Length; i++) { 7 if(array[i] > max) 8 max = array[i]; 9 } 10 Console.WriteLine("array數組中最大的值為:" + max); 11 Console.Read(); 12 } 13
14 }
顯然這不符合我們的要求,在《算法:C語言實現》一書中介紹分治法時候就是用的這個例子。
以下概念來自百度百科:
分治法的設計思想是,將一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。
分治策略是:對於一個規模為n的問題,若該問題可以容易地解決(比如說規模n較小)則直接解決,否則將其分解為k個規模較小的子問題,這些子問題互相獨立且與原問題形式相同,遞歸地解這些子問題,然后將各子問題的解合並得到原問題的解。這種算法設計策略叫做分治法。如果原問題可分割成k個子問題,1<k≤n ,且這些子問題都可解並可利用這些子問題的解求出原問題的解,那么這種分治法就是可行的。由分治法產生的子問題往往是原問題的較小模式,這就為使用遞歸技術提供了方便。在這種情況下,反復應用分治手段,可以使子問題與原問題類型一致而其規模卻不斷縮小,最終使子問題縮小到很容易直接求出其解。這自然導致遞歸過程的產生。分治與遞歸像一對孿生兄弟,經常同時應用在算法設計之中,並由此產生許多高效算法。
接下來我嘗試用自己的理解,結合手上的資料設計出使用分治法求數組最大值的方法。
以數組array為例:int[] array = new int[] { 2,4,5,6,23,24,21,66,21};
1.將函數分成array[0],array[1],...,array[4]和array[5],array[6],...,array[8]兩部分,逐步將問題為9的問題變成5和4的問題,再將5的問題變成3和2的問題,以此類推。最后變為都是1的問題。

圖1:表示將問題9的問題,逐步轉化成問題為1的子問題。
2.解決最小的問題(即是解決數組中兩數的大小,並返回大的數),此時可以看出比較后有返回值

圖2:代表array的索引值,每個橢圓節點表示一次遞歸函數的調用,方形節點表示每次遞歸調用的終結。

圖3:代表array的具體值,每個橢圓節點表示一次遞歸函數的返回值,方形節點表示每次遞歸調用的終結點的返回值。
3.由此我們可以想到肯定有個函數執行着這樣一個過程:
66 max(0,8)
23 max(0,4)
5 max(0,2)
4 max(0,1)
....
個人覺得遞歸算法的設計需要你有雙發現規律的眼睛。以下是實現代碼:
1 public class Test { 2 public static int m; 3 public static void Main(){ 4 int[] array = new int[] { 2,77,5,6,23,24,21,66,21}; 5 Console.WriteLine(GetMax(array, 0, 8)); 6 Console.Read(); 7 } 8 public static int GetMax(int[] array,int l,int r) { 9 int a, b; 10 m = (l + r) / 2; 11 if (l == m) return array[l]; 12 a = GetMax(array,l,m); 13 b = GetMax(array,m+1,r); 14 return a>b?a:b; 15 } 16 }
理解的不是很好。
新手,歡迎指教!
