時間複雜度
應該是計算機專業中乙個很重要的知識,重要到你有可能因為沒好好掌握而被面試官刷掉。正好現在大二正在學資料結構
,寫這篇部落格既是為了鞏固一下自己的掌握程度,同時也幫大家複習複習或是介紹一下。
為了用一種不受演算法所用語言以及編譯程式不同或機器效能
影響的方法來評估演算法的效率,我們通常選取所研究問題的基本操作
的執行次數
作為整個演算法的時間量度。但在某些情況下,演算法的執行次數計算可能難以計算。因此引入時間複雜度作為演算法規模大小的衡量工具,是對演算法效率好壞的一種非定量表示。
時間複雜度:
一般情況下,演算法中基本操作的重複執行次數是問題規模n的某個函式f(n) ,演算法的時間量度記作:t(n
)=o(
f(n)
)t(n)=o(f(n))
t(n)=o
(f(n
))它表示隨著問題規模n的增大,演算法執行時間的增長率不超過f(n)的增長率,也就是所謂的時間複雜度
基本操作:
基本操作
通常指演算法中最深層迴圈的語句,它也是演算法最核心
的語句,同時基本操作的重複執行次數與整個演算法的執行時間成正比
。通常是對變數的賦值、數**算等。一般通過演算法本身的目的來確定,比如,乙個交換排序演算法,其基本操作就是最內層的交換賦值操作。只有在確定了演算法的基本操作後,才能計算演算法的時間複雜度。
頻度(frequency count)
指基本操作的重複執行次數
,屬於定量
計算
第一步已經介紹過,下面著重講解中間兩個核心步驟
1.計算基本操作的頻度
拿幾個簡單的例子來說:
例1
int x=1;
++x;
那麼很簡單,基本操作是x的自增,同時它僅僅執行了一次。即頻度為1,而且它的執行次數與x的賦值大小無關,也就是與問題規模n無關,因此f(n)=1,即t(n)=o(1)
例2
for
(i=1
;i<=n;
++i)
與例1相似,++x的執行次數為n次,即f(n)=n,隨著問題規模n的增大,所需時間越多,且與n的大小成正比
例3
for
(i=1
;i<=n;i++
)}
例3也是同樣的道理,f(n)=n^2,不過是與二次方成正比
若遇到的是非常規問題,可以按以下方法處理(取自《資料結構》教材):
1.對於並列迴圈
結構,取各迴圈結構計算時間的最大值
2.對於巢狀迴圈
結構,取最內層迴圈體中語句的執行次數
3.若各迴圈之間無關係
,採用乘法原則,將各迴圈的次數相乘
4.對於遞迴演算法,分解為兩部分計算:
(1)執行目前層次的遞迴分解運算所需時間
(2)執行遞迴呼叫所需時間
2.將頻度轉為時間複雜度
由於頻度是定量的精確計算
,而時間複雜度是非定量的整體規模表示
,因此要簡化捨去計算所得頻度,即「化簡」f(n)
簡化原則:
1.刪掉常數項以及常數係數
2.去掉低階項,保留最高端項
簡化舉例:
對於某演算法,
原 f(
n)=5
n2+7
n+
9原f(n)=5n^2+7n+9
原f(n)=
5n2+
7n+9
簡 化後
f(n)
=n
2簡化後f(n)=n^2
簡化後f(n
)=n2
因此該演算法時間複雜度為
t (n
)=o(
n2
)t(n)=o(n^2)
t(n)=o
(n2)
符號o的解釋(也是從數學角度解釋為什麼可以簡化):
為了不含糊,這裡解釋一下為什麼是用符號o來表示時間複雜度。這裡要特別宣告這個符號與高數中表示高階無窮小的小o()符號不是乙個東西現有如下**
int
function
(int n)
return sum;
}
答案鏈結如下: 每天一道演算法題 時間複雜度為O n 的排序
有1,2,一直到n的無序陣列,求排序演算法,並且要求時間複雜度為o n 空間複雜度為o 1 使用交換,而且一次只能交換兩個數。這個是以前看到的演算法題,題目不難。但是要求比較多,排序演算法中,時間複雜度為o n 就是基數排序了。現在介紹兩種解法 解法一 用陣列特性 下標實現交換 掃瞄陣列,每次arr...
黑馬程式設計師學習筆記 關於時間複雜度計算2
asp.net unity開發 net培訓 期待與您交流!以上三條單個語句的頻度均為1,該程式段的執行時間是乙個與問題規模n無關的常數。演算法的時間複雜度為常數階,記作t n o 1 如果演算法的執行時間不隨著問題規模n的增加而增長,即使演算法中有上千條語句,其執行時間也不過是乙個較大的常數。此類演...
一道演算法題 降低空間複雜度的思考
最近在看演算法 第四版 裡面有一道演算法題。第一次寫的時候,採用了雙層巢狀,時間複雜度為o n 2 後來發現時間複雜度可以降低到o n 原題 編寫乙個靜態方法histogram 接受乙個整型陣列a和乙個整數m為引數並返回乙個大小為m的陣列,其中第i個元素的值為整數i在引數陣列中出現的次數。如果a中的...