递归算法经典实例小结(C#实现)
在數學與計算機科學中,遞歸是指在函數的定義中使用函數自身的方法。
遞歸算法是一種直接或者間接地調用自身算法的過程。在計算機編寫程序中,遞歸算法對解決一大類問題是十分有效的,它往往使算法的描述簡潔而且易于理解。
遞歸算法解決問題的特點:
(1) 遞歸就是在過程或函數里調用自身。
(2) 在使用遞歸策略時,必須有一個明確的遞歸結束條件,稱為遞歸出口。
(3) 遞歸算法解題通常顯得很簡潔,但遞歸算法解題的運行效率較低。所以一般不提倡用遞歸算法設計程序。
(4) 在遞歸調用的過程當中系統為每一層的返回點、局部量等開辟了棧來存儲。遞歸次數過多容易造成棧溢出等。所以一般不提倡用遞歸算法設計程序。在實際編程中尤其要注意棧溢出問題。
借助遞歸方法,我們可以把一個相對復雜的問題轉化為一個與原問題相似的規模較小的問題來求解,遞歸方法只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量。但在帶來便捷的同時,也會有一些缺點,也即:通常用遞歸方法的運行效率不高。
?
?二 、Fibonacci數列和階乘1、?Fibonacci數列
提到遞歸,我們可能會想到的一個實例便是斐波那契數列。斐波那契數列就是如下的數列:
??0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …,總之,就是第N(N > 2)個數等于第(N - 1)個數和(N - 2)個數的和。用遞歸算法實現如下:
public static int Fibonacci(int n){if (n < 0) return -1;if (n == 0) return 0;if (n == 1) return 1;return Fibonacci(n - 1) + Fibonacci(n - 2);}?
2、階乘?
還有就是求一個數的階乘,也會用到遞歸,這個比較簡單,直接給出實現代碼,如圖:
?
?三 、漢諾塔問題?漢諾塔是根據一個傳說形成的數學問題:
? ? ?漢諾塔示意圖(圖片來自網絡)
?有三根桿子A,B,C。A桿上有N個(N>1)穿孔圓盤,盤的尺寸由下到上依次變小。要求按下列規則將所有圓盤移至C桿:
1、每次只能移動一個圓盤;
2、大盤不能疊在小盤上面。
提示:可將圓盤臨時置于B桿,也可將從A桿移出的圓盤重新移回A桿,但都必須遵循上述兩條規則。
問:如何移?最少要移動多少次?
?下面是漢諾塔的遞歸求解實現(C#代碼):
public static void hannoi(int n, string from, string buffer, string to){if (n == 1){Console.WriteLine("Move disk " + n + " from " + from + " to " + to);}else{hannoi(n - 1, from, to, buffer);Console.WriteLine("Move disk " + n + " from " + from + " to " + to);hannoi(n - 1, buffer, from, to);}}其運行結果如圖(大家可以跟上面的gif圖片對比一下):
?
?四 、排列組合1、輸出任意個數字母、數字的全排列?
對于一個長度為n的串或者n個字符(數字、節點)組成的字符串數組,它的全排列共有A(n,?n)=n!種。這個問題也是一個遞歸的問題。如1,2,3,全排列可得到:{123,132,213,231,312,321}。
用遞歸算法實現代碼如下:
public static void Permutation(string[] nums, int m, int n){string t;if (m < n - 1){Permutation(nums, m + 1, n);for (int i = m + 1; i < n; i++){//可抽取Swap方法t = nums[m];nums[m] = nums[i];nums[i] = t;Permutation(nums, m + 1, n);//可抽取Swap方法t = nums[m];nums[m] = nums[i];nums[i] = t;}}else{for (int j = 0; j < nums.Length; j++){Console.Write(nums[j]);}Console.WriteLine();}}調用代碼如下:
static void Main(string[] args){Nums = new string[] { "a", "b", "c" };Permutation(Nums, 0, Nums.Length); Console.ReadKey();}?這里傳入一個string數組,abc三個字母來測試,輸出如下圖:
?
2、將全排列結果保存到鏈表中
有時候,我們需要將全排列的結果保存,然后做其他的處理,我們可以將結果保存到一個鏈表中。我們定義如下類作為鏈表的節點,代碼如下:
public class Node{public string value { get; set; }public Node nextNode { get; set; }public Node(string value){this.value = value;this.nextNode = null;}}?此時聲明全局變量,如下:
public static List<Node> NodeList = new List<Node>();這個時候,我們修改Permutation方法,如下:
public static void Permutation(string[] nums, int m, int n){string t;if (m < n - 1){Permutation(nums, m + 1, n);for (int i = m + 1; i < n; i++){//可抽取Swap方法t = nums[m];nums[m] = nums[i];nums[i] = t;Permutation(nums, m + 1, n);//可抽取Swap方法t = nums[m];nums[m] = nums[i];nums[i] = t;}}else{Node root = null;Node currentNode;for (int j = 0; j < nums.Length; j++){currentNode = new Node(nums[j]);currentNode.nextNode = root;root = currentNode;}NodeList.Add(root);}}這樣,我們執行了Permutation方法后,就將結果保存到鏈表中了。用的時候,我們只要遍歷NodeList就可以了。如圖:
?遞歸算法就先說到這里了。談到算法,就必需提數據結構,看來真的要“學到老了”~~
?
?作者:雲霏霏
QQ交流群:243633526
?博客地址:http://www.cnblogs.com/yunfeifei/
?聲明:本博客原創文字只代表本人工作中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關系。非商業,未授權,貼子請以現狀保留,轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
如果大家感覺我的博文對大家有幫助,請推薦支持一把,給我寫作的動力。
?
總結
以上是生活随笔為你收集整理的递归算法经典实例小结(C#实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DPtoLP/LPtoDP 和 Scre
- 下一篇: 人事薪资管理系统V1.00功能简介(适用