j我們知道學習資料結構與演算法主要是解決乙個「快」和「省」的問題,如何讓**執行更快、如何更節省空間。那麼如何來考量你的**的執行效率呢,我們總要有乙個標準,這就是我今天所講的複雜度分析,不誇張的說,掌握好複雜度分析,資料結構與演算法你就掌握了一半,所有的演算法都逃不出複雜度分析的範疇。
複雜度分析包括時間複雜度和空間複雜度。
如何考量我們**的執行效率,有的人可能會說我在計算機上跑一下不得了,簡單便捷,沒錯,這樣確實可以。但是這種方法太依賴硬體環境了,你在不同的機器上跑的時間肯定是不一樣的。所以,我們需要一種不依靠測試環境,不需要測試資料的方法來估計演算法的執行效率的方法。大 o 時間複雜度上場了。
大 o 複雜度表示法
直接上**,我會帶你一起來估算**的執行時間,在實戰中掌握大 o 複雜度。
int sum(int n)return sum;
上面是乙個計算從 1 + 2 + 3 + ··· + n 的求和,我們假設每行**的執行時間都是乙個 unit_time。我們可以看到第 3、4 行的**都執行了 1 個 unit_time,第 6、8 行都執行了 n 個 unit_time。所以這段**執行時間為 t(n) = (2n+2) * unit_time。即 t(n) = o(2n+2), 這就是大 o 時間複雜度表示法。當 n 趨向於無窮大時,記為 t(n) = o(n)。
大 o 時間複雜度表示法實際上並不表示**真正的執行時間,大家也看到了,t(n)才是**真正的執行時間,大 o 時間複雜度是表示**執行時間隨資料規模增長的變化趨勢。
演算法的時間複雜度採用這種數量級的形式表示後,將給分析演算法的時間複雜度帶來很大的方便。即對乙個演算法,只需分析影響該演算法時間複雜度的主要部分即可,而無需對該演算法的每乙個語句都進行纖細的分析。
時間複雜度分析
那麼問題來了,給我們一段**,我們怎麼分析它的時間複雜度呢?我有二個實操的方法可以分享給你。
1. 關注執行次數最多的一段**
在上面那個例子中,執行次數最多的是第 6、8 行,所以總的時間複雜度就是 o(n)。
2. 關注量級最大的那段**
看下面**,你可以先試著分析一下,再往下翻。
int sum(int n)int sum_2 = 0;int q = 1;for(; q n; q++) int sum_3 = 0;int i = 1;for(; i=n; i++) return sum_1 + sum_2+ sum_3;
第一段執行了 10 次,這是乙個常量的執行時間,跟 n 的規模無關,就算它執行一百次、一千次,它也是常量級的執行時間。所以為 o(1)。
第二段和第三段**分別為 o(n)、o(n2),這對你應該不是很難。所以我們只關注量級最大的**的時間複雜度,即 o(n2)。
大 o 表示法有乘法法則和加法法則,非常好理解,乘法法則實際上就是巢狀迴圈。相信你已經懂了時間複雜度的大 o 分析法了。
下面我介紹一些常見的時間複雜度分析例項。
(敲黑板,劃重點了,拿小本本記下)
1. o(1)
o(1) 常量級時間複雜度
int x = 1;
int y = 2;int sum = x + y;
1. o(logn)
i = 1;while( i = n)
i = i * 2;
**的執行次數為 x = log2n,即求解方程 2x = n。
演算法學習 演算法的時間複雜度與空間複雜度
乙個演算法執行所耗費的時間,從理論上來說是不能計算出來的,必須通過上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。...
演算法複雜度分析
分析非遞迴演算法效率的通用方案 1.決定用哪個 哪些 引數作為輸入規模的度量 2.找出演算法的基本操作 作為一規律,它總是位於演算法的最內層迴圈中 3.檢查基本操作的執行次數是否只依賴輸入規模。如果它還依賴一些其他的特性,則最差效率 平均效率以及最優效率 如果必要 需要分別研究。4.建立乙個演算法基...
演算法複雜度分析
演算法分析的四個漸進表示法 一般,o裡的,取最小的 一般,裡的,取最大的 一般分析時間複雜度,且常考慮最壞複雜度,常用o分析 三法則 法則一 如果t1 n o f n t2 n0 o g n t1 n t2 n max o f n o g n t1 n t2 n o f n o g n 法則二 如果...