演算法小談 遞迴

2021-09-19 18:02:56 字數 3352 閱讀 3332

基本概念:乙個函式呼叫它自身,就是遞迴

如求n的階乘的遞迴:

#includeusing namespace std;

int factorial(int n)

int main()

這裡在求n的階乘時,我們就用到遞迴的概念。假如n=3,那麼函式首先呼叫factorial(3),將函式呼叫壓入棧,繼續呼叫factorial(2),繼續壓入棧,呼叫factoral(1),factoral(1)此時處於棧頂位置,因為n==1時,函式返回1,所以執行完factoral(1)後,**棧的函式呼叫就會先被彈出來,隨後執行factorial(2),繼續彈出,直到factorial(3)被執行,全部函式呼叫都被彈出,函式執行完畢,所以遞迴的過程就是不斷壓棧出棧的過程。

遞迴的作用:

可以看到,遞迴的作用有點類似與迴圈,但遞迴可能從某方面來說,能使得解決方案更清晰,其實並沒有效能上的優勢,實際上,在有些情況下,使用迴圈的效能更好。總而言之,借用某個大牛的話:使用迴圈可能會使得你的程式效能更高,但使用遞迴,可能會然後你的程式看起來更容易理解。

基本思路:該題就是乙個排列組合問題,主要利用遞迴來解決,因為字元的個數不大於6個。因此我們可以用乙個字元陣列來存貯不同組合下的變化情況,另外,為了輸出不同的排列,還需要設定乙個訪問標誌位,具體程式如下所示:

要注意的是,遞迴的條件需要包含兩個:基線條件和遞迴條件。遞迴條件是能讓你的程式使得問題能夠一步步的被分解,直到分解成最小規模求解問題,基線條件就是為了防止程式無限分解下去,即陷入死迴圈,所以這個條件也可以稱之為邊界條件。

#include#include#includeusing namespace std;

string s1; //輸入字串

char s2[6]; //用來存放不斷調整的字元組合

int visit[6] = ; //判斷字串某一位是否被訪問的標誌位

int len; //字串的長度

void out_result(int steps)

for (int i = 0; i < len; i++) }}

int main()

執行程式,輸入測試樣本,列印結果如下:

基本思路:從體重我們可以看到,當冪的大小小於4的時候,其實可以當作一種特殊情況,即遞迴的邊界條件,有了邊界條件,就可以對程式進行遞迴。

#include#include#includeusing namespace std;

int power_func(int x)

power_func(x - pow(2,max_power - 1)); //繼續遞迴x-第一輪小於x的2的最大冪次方

} else }}

int main()

輸入測試資料,得到結果如下所示:

基本思路:這一題和四則運算表示式的思路相似,同樣是將表示式分為項和因子來進行遞迴。

#include#include#include#includeusing namespace std;

char s[10000] = ;

bool expression_value();

bool term_value();

bool factor_value();

int my_cent;

bool term_value()

else

return result;

}bool factor_value()

else if (o == 'v')

else if (o == 'f')

else if (o == '!')

return result;

}bool expression_value()

else

} return result;

}int main();

int len = strlen(s);

int n = 0;

for (int i = 0; i < len; i++)

} //cout << k;

len = strlen(t);

for (int i = 0; i < len; i++)

s[len] = '\0'; //到這一步,輸入字元中的空格被去除

cout << "expression " << ++k << ": " << (expression_value() ? 'v' : 'f') << endl;

my_cent = 0;

memset(s, 0, 10000);

} system("pause");

return 0;

}

基本思路:如果中的最大值不超過m,即max(m1,m2,...,mi)<=m,則稱它屬於n的乙個m劃分。這裡我們記n的m劃分的個數為f(n,m);例如但n=4時,他有5個劃分,,,,,;注意4=1+3 和 4=3+1被認為是同乙個劃分。該問題是求出n的所有劃分個數,即f(n, n)。下面我們考慮求f(n,m)的方法;

(1)當n=1時,不論m的值為多少(m>0),只有一種劃分即;

(2)當m=1時,不論n的值為多少,只有一種劃分即n個1,;

(3)當n=m時,根據劃分中是否包含n,可以分為兩種情況:

(a)劃分中包含n的情況,只有乙個即;

(b)劃分中不包含n的情況,這時劃分中最大的數字也一定比n小,即n的所有(n-1)劃分。

因此 f(n,n) =1 + f(n,n-1);

(4)當n(5)但n>m時,根據劃分中是否包含最大值m,可以分為兩種情況:

(a)劃分中包含m的情況,即}, 其中 的和為n-m,因此這情況下

為f(n-m,m)

(b)劃分中不包含m的情況,則劃分中所有值都比m小,即n的(m-1)劃分,個數為f(n,m-1);

因此 f(n, m) = f(n-m, m)+f(n,m-1);

#includeusing namespace std;

int equationcount(int n, int m)

int main()

return 0;

}

遞迴優點:

1. 簡潔

2.在樹的前序,中序,後序遍歷演算法中,遞迴的實現明顯要比迴圈簡單得多。

遞迴缺點:

2.遞迴中很多計算都是重複的,由於其本質是把乙個問題分解成兩個或者多個小問題,多個小問題存在相互重疊的部分,則存在重複計算,如fibonacci斐波那契數列的遞迴實現。->效率

3.呼叫棧可能會溢位,其實每一次函式呼叫會在記憶體棧中分配空間,而每個程序的棧的容量是有限的,當呼叫的層次太多時,就會超出棧的容量,從而導致棧溢位。->效能

Hash演算法小談

hash演算法小談 一 初識hash 一直都只知道hash是一種演算法,但是具體是什麼一直都是模糊的概念。之前知道object類中有hashcode 方法,此方法返回該物件的雜湊碼值。而雜湊碼值物件的記憶體位址。hash其實就是一種儲存資料的結構,一般來說我們所了解熟 悉的結構有 陣列 鍊錶 佇列 ...

小談C STL演算法 sorting

c stl 也提供了排序演算法 sorting algorithms 排序就是將一組無序的序列變成有序的序列.首先介紹一下關於堆排序的內容 下面就是關於堆排序的一些演算法函式 push heap 元素入堆 就是將乙個元素置入已構成的堆的迭代器區間中 使得擴充套件的乙個元素的區間元素仍構成堆 會改變迭...

遞迴迴圈子元件 遞迴演算法小知識

遞迴演算法是把問題轉化為規模縮小了的同類問題的子問題,然後遞迴呼叫函式 或過程 來表示問題的解。乙個過程 或函式 直接或間接呼叫自己本身,這種過程 或函式 叫遞迴過程 或函式 遞迴過程一般通過函式或子過程來實現。遞迴方法 在函式或子過程的內部,直接或者間接地呼叫自己的演算法。遞迴其實就是在棧記憶體中...