遞迴的實質以及遞迴時間複雜度的計算
說到遞迴,總會提到這麼幾個問題:
遞迴和迭代的區別是什麼?
答:迭代式調別人,而遞迴是調自己
遞迴能不能改為迭代?
答:可以
那麼遞迴的實質是什麼?今天就說一下遞迴的實質
1.遞迴的實質:壓系統棧
壓到棧裡的是當前的所有資訊,包括當前跑到多少行,當前的引數和函式內的引數變數,等等
返回後再進行彈棧,然後讀取彈棧後棧頂空間的資訊,也就是返回到呼叫的地方。
我們也常常會說,遞迴可能會導致記憶體溢位也就是因為棧太過深了才可能會導致記憶體溢位。
遞迴可以改成迭代的原因就是,遞迴是系統在幫我們壓棧,我們當然可以自己去申請棧空間進行操作,所以當然是可以改成迭代的。
2.遞迴空間複雜度
一般的空間複雜度可以使用master公式計算:
T(N) = aT(n/b) + O(N^d)
T(N):父問題的樣本量
a:呼叫模組發生的次數
T(N/b):子問題的樣本量
O(N^d):除去子問題呼叫過程外,剩下部分的時間複雜度
1) log(b,a) > d -> 複雜度為O(N^log(b,a))
2) log(b, a) = d -> 複雜度為O(N^d * logN)
2) log(b, a) < d -> 複雜度為O(N^d)
舉個例子:
/*
* 遞迴二分求最大數
*/
public static int getMaxNum (int[] arr, int L, int R) {
// 遞迴結束條件:只剩下一個數
if(L == R)
return arr[L];
int mid = L +((R - L) >> 1); //位運算取中值
int leftMax = getMaxNum(arr, L, mid); //T(N/2)
int rightMax = getMaxNum(arr, mid + 1, R); //T(N/2)
return Math.max(leftMax, rightMax); //O(1)
}
// for test
public static void main(String[] args) {
int[] arr = {2, 3, 1, 6, 5};
System.out.println("max = " + getMaxNum(arr, 0, arr.length - 1));
}
從以上程式碼中分析
1.遞迴過程:
主函式呼叫getMax方法,第一次壓棧是在int leftMax = getMaxNum(arr, L, mid);
處,此時存入棧中的資訊有:此時程式碼執行到的行數、該方法的引數:L = 0,mid = 2等,將此時的所有資訊儲存在申請的棧空間中,然後再進入調的getMaxNum方法中。。。一旦當前的L == R,即觸發了return arr[L];
此時進行彈棧操作,讀取彈棧後的棧頂的資訊,完全還原當時的資訊,再繼續執行。
2.遞迴時間複雜度的計算
T(N) = aT(n/b) + O(N^d)
T(N) = 2T(n/2) + O(N^0)
a = 2,b = 2,d = 0
可以使用master公式:
滿足:log(b,a) > d -> 複雜度為O(N^log(b,a))
時間複雜度即為:O(N^1) = O(N)
相關推薦
遞迴演算法的時間複雜度計算
在演算法分析中,當一個演算法中包含遞迴呼叫時,其時間複雜度的分析會轉化為一個遞迴方程求解。實際上,這個問題是數學上求解漸近階的問題,而遞迴方程的形式多種多樣,其求解方法也是不一而足,比較常用的有以下四種方法: (1)代入法(Substitution Metho
【資料結構】實現順序表以及簡單的時間複雜度分析
最近在學資料結構,接下來一段時間我將用java來實現所學的各種資料結構,以加深自己的印象。 線性表包括順序表和連結串列,其實順序表就是動態陣列,下面我將二次封裝實現屬於自己的動態陣列。 -------------------------------------------
徹底輕鬆搞定順序儲存結構元素的二分查詢的時間複雜度優勢以及如何算時間複雜度
二分查詢也叫折半查詢,根據字面意思大概知道是怎麼個查詢具體一個元素的吧。 首先分析下查詢過程: 我們先通過被查詢的陣列得到該被查詢陣列的第一個索引和最後一個索引值,假如我們拿陣列10個元素來做例子 我們得到索引0和索引9 mid = (min(0)
設計一個堆疊,函式min、push 以及pop 的時間複雜度都是O(1)
/** * 2.設計包含min 函式的棧。 * 定義棧的資料結構,要求新增一個min 函式,能夠得到棧的最小元素。 * 要求函式min、push 以及pop 的時間複雜度都是O(1)。 * * 經典的空間換取時間,這個是利用java語言的JDK的實現的
線性表——順序表——時間複雜度計算
資料結構的核心思想是通過資料結構的思維來優化程式碼的演算法,以此來提升程式的執行效能,縮短程式執行的時間。下面我來舉兩個例子,以此來說明資料結構的時間複雜度計算問題。 由於我這裡操作的是線性表——順序表,所以說先把線性表——順序表的原始碼貼出來 Ab
線性表——順序表——時間複雜度計算2
接上一篇文章繼續分析 在之前的文章中的示例1和示例2中,我們通過觀察可以發現,當在順序儲存結構的線性表中某個位置上插入或刪除一個數據元素時,其時間主要耗費在移動元素上(換句話說,移動元素的操作為預估演算法時間複雜度的基本操作),而移動元素的格式
資料結構-演算法-時間複雜度計算
演算法的時間複雜度定義為: 在進行演算法分析時,語句總的執行次數T(n)是關於問題規模n的函式,進而分析T(n)隨n的變化情況並確定T(n)的數量級。演算法的時間複雜度,也就是演算法的時間量度,記作:T(n}=0(f(n))。它表示隨問題規模n的增大,演算法執行時間的埔長率
資料結構與演算法-時間複雜度計算
一、方法 根本沒有必要計算時間頻度,即使計算處理還要忽略常量、低次軍和最高次剩的係數,所以可以採用如下簡單方法: 找出演算法中的基本語句:演算法中執行次數最多的那條語句就是基本語句,通常是最內層迴圈的迴圈體。 計算基本語句的執行次數的數量級:只需計算基本語句執行次數的數量級,這就
演算法複雜度的評估以及常用函式的複雜度計算
一、評估演算法複雜度 舉例: 演算法複雜度為O(n): 演算法複雜度為O(n2): 演算法複雜度為O(1+2+...+n) ---> O(n2): 演算法複雜度為O(lgN):
演算法之漢諾塔時間複雜度計算
設a, b, c是3個塔座:開始時,塔座a上有n個自上而下、由小到大地疊在一起圓盤,各圓盤從小到大編號為1, 2, …, n,現要求將塔座a上的這一疊圓盤移到塔座b上,並仍按同樣順序疊置,移動圓盤時遵守以下移動規則: 規則1:每次只能移動1個圓盤; 規則2:不允許將較大的圓
演算法的時間複雜度計算
時間複雜度與演算法步驟的多少是同樣的含義,計算演算法的總步驟就是時間複雜度。同時大O表示的是時間複雜度的上限。所以計算總步驟時可以按同數量級中最大情況來計算。 1.O(f(n)):輸入規模為n(n個數據)的演算法的時間複雜度為f(n)。 2.O(1):演算法的時間複雜度與輸
演算法時間複雜度計算方法
一、概念: 時間複雜度是總運算次數表示式中受n的變化影響最大的那一項(不含係數) 比如:一般總運算次數表示式類似於這樣: a*2^n+b*n^3+c*n^2+d*n*lg(n)+e*n+f a ! =0時,時間複雜度就是O(2^n); a=0,b<
資料結構-時間複雜度計算詳解--向李紅老師的資料結構低頭 :)
今天早上突然想總結一下資料結構的時間複雜度的知識。 之前學了很多遍,但是一直沒有總結,所以之前參考了Algorithm還有清華大學出版的那個資料結構書,今天早上花了幾個小時好好的總結一下,也送給三班的同學們。 演算法的時間複雜度定義為: 在
二分法的時間複雜度+演算法的時間複雜度計算
黃色標亮-劃重點背誦+自己的理解,綠色標亮-引用資源的連結,藍色標亮-要注意的地方 二分法查詢 的 時間複雜度計算 設 查詢資料的長度為n,每次查詢後資料長度減半,則有 查詢次數 資料長度 第1次查詢 n/2
快速排序平均情況下時間複雜度計算過程:
就平均情況而言,快速排序是目前被認為最好的一種內部排序方法,其時間複雜度在平均情況下是nlogn,在最壞的情況下(有序時)時間複雜度是o(n^2)。下面來分析時間複雜度的計算過程: 平均情況下:T(n)=2*T(n/2)+n; 第一次劃分
時間複雜度計算
定義:如果一個問題的規模是n,解這一問題的某一演算法所需要的時間為T(n),它是n的某一函式 T(n)稱為這一演算法的“時間複雜性”。 當輸入量n逐漸加大時,時間複雜性的極限情形稱為演算法的“漸近時間複雜性”。 我們常用大O表示法表示時間複雜性,注意它是某一個演算法的時間複雜性。大O表示只是說有上界,由定義如
遞迴的實質以及遞迴時間複雜度的計算
說到遞迴,總會提到這麼幾個問題: 遞迴和迭代的區別是什麼? 答:迭代式調別人,而遞迴是調自己 遞迴能不能改為迭代? 答:可以 那麼遞迴的實質是什麼?今天就說一下遞迴的實質 1.遞迴的實質:壓
空間複雜度、時間複雜度、遞迴
//空間複雜度:實現演算法需要的額外的輔助空間 //時間複雜度:①只保留高階項,低階項直接丟棄//  
遞迴樹——藉助樹來求解遞迴演算法的時間複雜度
遞迴程式碼的時間複雜度分析起來非常麻煩,今天我們嘗試來藉助遞迴樹分析遞迴演算法的時間複雜度。 1. 遞迴樹與時間複雜度分析 遞迴的思想就是將大問題一層一層地分解為小問題來求解,如果我們把這個分解過程畫成圖,它其實就是一棵樹,我們稱之為遞迴樹。 上圖為斐波那契數列的遞迴樹,節點裡的數字表示資
遞迴呼叫與時間複雜度的學習總結
今天主要學習了兩個知識點。分別是遞迴呼叫和時間複雜度。重點是時間複雜度,比較複雜 。 1. 遞迴函式 1.1題目1: 一共5個人,一個比一個大2歲,最後一個10歲,問第一個多少歲? 首先用迴圈形式來寫函式,如下: int Age1(int n)//O