分析时间复杂度和空间复杂度(一级)
生活随笔
收集整理的這篇文章主要介紹了
分析时间复杂度和空间复杂度(一级)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
什么叫時(shí)間復(fù)雜度,并且告訴大家我們一般求時(shí)間最壞復(fù)雜度,下邊我們該怎么求時(shí)間復(fù)雜度呢,沒有必要去求他真實(shí)的計(jì)算次數(shù),所以我們最后把這個(gè)問題簡化了,怎么來簡化?1. 找出算法中的基本語句,基本語句是哪個(gè)語句呢,一般來說是執(zhí)行次數(shù)最多的那條語句,其他的都可以省略,找算法中的基本語句,算法中執(zhí)行次數(shù)最多的那條語句就是基本語句2. 然后我們只要計(jì)算基本語句的執(zhí)行次數(shù)的級(jí)別就可以了3. 最后用大O來表示下邊我們都舉幾個(gè)列子都挺簡單的
時(shí)間復(fù)雜度舉例(1)----------------------------------------------------一個(gè)簡單語句的時(shí)間復(fù)雜度為O(1).int count = 1;他的時(shí)間復(fù)雜度是多少,我們不是應(yīng)該這么求嗎,T(n)=1,因?yàn)橐粭l語句他的執(zhí)行次數(shù)就是一次,這不叫時(shí)間復(fù)雜度,這叫時(shí)間頻度,時(shí)間復(fù)雜度是怎么來的,T(n)=O(1),第一步找出基本語句,他的執(zhí)行次數(shù)就一次,再用大歐來表示,他沒有低次冪,只有常數(shù)項(xiàng),這用1來表示就可以了(2)-----------------------------------------------------100個(gè)簡單語句的事件復(fù)雜度也為O(1).int count = 0;
int count = 0;
int count = 0;
........
int count = 0;int不能重復(fù)的定義,一共一百條語句,請你告訴我,他的執(zhí)行次數(shù),他的時(shí)間復(fù)雜度是多少,找出基本語句,每個(gè)語句執(zhí)行一次,那就是T(n)=1,T(n)=O(1),還是1,我不找基本語句,只是100條語句,他的執(zhí)行次數(shù)是100,T(n)=100,不找基本語句,所有的語句執(zhí)行次數(shù)是100,T(n)=100,但是時(shí)間復(fù)雜度來求的話100都要去掉,去掉之后就變成1了,T(n)=O(1),有人說這里是100條,但是這里不管是1萬條還是10萬條,這里最后還是1,因?yàn)?0萬條還是個(gè)有限的數(shù),他也是個(gè)常數(shù),這一點(diǎn)大家明確(3)----------------------------------------------------一個(gè)循環(huán)的時(shí)間復(fù)雜度為O(n)int n = 8,count = 0;for(int i=1;i<=n;i++){count++;
}一個(gè)循環(huán)的事件復(fù)雜度,n等于8,count等于0,for循環(huán)循環(huán)幾次,count加加,注意啊,你不要看這個(gè)8,因?yàn)檫@次給個(gè)8,下次給的可能就不是8了,也可能是給個(gè)無窮大的數(shù),他就是個(gè)變量,請問他的時(shí)間復(fù)雜度是多少,注意了,要找基本語句,基本語句是不是int n = 8,count = 0這條語句,基本語句執(zhí)行次數(shù)最多的語句,最多的是count++,有些人會(huì)說最多的是i<=n,不計(jì)較這個(gè),計(jì)較這個(gè)有意義嗎,是沒有意義,我們找循環(huán)體就可以了,那你想一下,count++這個(gè)他應(yīng)該執(zhí)行多少次,我們要寫T(n),告訴我他執(zhí)行多少次,那是不是和n有關(guān),那就執(zhí)行n次吧,T(n)=n,T(n)=n+1,和T(n)=n-1次這個(gè)沒關(guān)系,我們就n次,這個(gè)n就可以了,不影響結(jié)果,然后怎么辦,如果T(n)用時(shí)間復(fù)雜度來表示,寫一個(gè)大歐還是n,T(n)=O(n),還是n就可以了,n相當(dāng)于一個(gè)變量,我想問大家一下,如果我這里寫的是10n+100,for(int i=1;i<=10n+100;i++),請告訴我,他的時(shí)間度是多少,那他的T(n)=10n+100,這個(gè)是時(shí)間頻度,但是我們是看復(fù)雜度,看他規(guī)模就可以了,怎么看呢,常數(shù)項(xiàng)100去掉,10n的系數(shù)10也去了,是不是還是n,多做幾個(gè)就明白了,是O(n)(4)------------------------------------------------------時(shí)間復(fù)雜度為O(log2 n)的循環(huán)語句int n = 5,count = 0;for(int i=1;i<=n;i*=2){count++;
}有人說這個(gè)語句和上面的語句一樣啊,不一樣,哪兒不一樣?關(guān)鍵是這兒i*=2,這兒不一樣,i乘等于2,這個(gè)時(shí)間度是多少,它執(zhí)行多少次,你知道i*=2是什么含義嗎,第一次它是1,然后他變成幾了,它變成2,然后就變成4,然后變成8,然后16,然后32,有人說這個(gè)變化也不快,這還叫不快嗎,好像大家都還聽說過一個(gè)故事,什么故事啊,什么印度一個(gè)國王,向國際象棋發(fā)明者老智者要賞賜他了我賞賜你糧食吧,一個(gè)國際象棋的棋盤,一共64個(gè)格,第一個(gè)格放一個(gè),第二個(gè)放2個(gè),第三個(gè)放4個(gè),第四個(gè)放8個(gè),當(dāng)時(shí)國王發(fā)現(xiàn)整個(gè)國家的糧食放進(jìn)來也放不夠,為什么啊,只有64個(gè)格,他就放不下了,別說64個(gè)格,想一下30個(gè)格就是多少,1是2的0次方,2是2的一次方,4是2的2次方,30個(gè)格那不就是2的30次方,2的30次方是多少啊,這對我們學(xué)計(jì)算機(jī)的來說應(yīng)該很清楚啊,不就是2的10次方乘以2的10次方,再乘以2的10次方,那不就是1024*1024*1024,我們簡單一下=1000*1000*1000,就是10的9次方,就是10億,想說明一個(gè)什么意思,也就是說,對于我們上面這個(gè)來說,我們最后寫的這個(gè)數(shù),如果我們呢這個(gè)數(shù)是n,他等于10億的話,這個(gè)i++,每次加的話,如果這個(gè)數(shù)是10億的話,它這個(gè)循環(huán)得循環(huán)多少次,i++一直變到10億,10億次,但是如果用(int i=1;i<=n;i*=2)這種方式的話幾次就可以了,如果這個(gè)n是10億的話,30次左右就可以了,有沒有想到我這個(gè)30次和10億次的差別,還是很大的,這種算法告訴我,我知道10億了,我知道這個(gè)n了,我怎么知道n的多少次方就等于n了,log2 n,一個(gè)叫做指數(shù),一個(gè)叫做對數(shù),反過來的,有的人說我有點(diǎn)糊涂了,我們在這里不做過多的糾結(jié),在這種情況下,我們要掌握兩點(diǎn),第一點(diǎn)log2 n的話,他的效率是特別高,你就想這個(gè)30次跟10億次的差別就可以了,想那個(gè)差別就可以了,如果你以后設(shè)計(jì)了一種算法,從O(n)到O(log2 n),那你太棒了,如果你再實(shí)現(xiàn)一種算法復(fù)雜度是O(1),那你就更厲害,這個(gè)大家明確了,這個(gè)log2 n就指數(shù)的反過來,2的30次方就是10億,這里特別標(biāo)記一下,好好的想一下這一塊(5)--------------------------------------------------------------時(shí)間復(fù)雜度為O(n2)的二重循環(huán).int n = 8,count=0;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){count++;}
}大家一定要記住,有人說這個(gè)有點(diǎn)難,難你不學(xué)肯定學(xué)不會(huì),不可能瞇一會(huì)睜開眼就回來,我們學(xué)就是學(xué)別人不會(huì)的,就學(xué)這些唄,學(xué)一些難的內(nèi)容,別人學(xué)不會(huì)我們會(huì)的,第三點(diǎn)這個(gè)真的很難嗎,我們今天就可以掌握就變成自己的了,這差距有時(shí)候就是這么來產(chǎn)生的,告訴我這個(gè)時(shí)間復(fù)雜度是多少,先找基本語句,基本語句是count++唄,這是基本語句,告訴我j<n是從1開始的,i小于n也是1開始的,我們不說別的,里循環(huán),里循環(huán)小循環(huán)多少次,從1到n次,這個(gè)n次有幾個(gè)n次,這外循環(huán)又是n次,那不就是n乘以n嗎,所以他的復(fù)雜度是O(n2),如果我這里要是10n呢,for(int j=1;j<=10n;j++),我這里是100n呢,for(int i=1;i<=100n;i++),級(jí)別是不是還是n的平方時(shí)間復(fù)雜度嗎,T(n)=100n*10n最后等于多少,最后等于1000n*10n,那我們要用時(shí)間復(fù)雜度來說,就等于T(n)=O(n*n),一步一步來,(6)--------------------------------------------------------------------時(shí)間復(fù)雜度為O(nlog2 n)的二重循環(huán)int n = 8,count = 0;for(int i=1;i<=n;i*=2){for(int j=1;j<=n;j++){count++;}
}總覺得很相似,j小于等于n,i小于等于n一樣啊? i*=2這兒不一樣,是不是這兒不一樣,雙重循環(huán),這里多少,在這個(gè)里循環(huán)里面多少次,里循環(huán)里面n次,他有多少個(gè)n次,他有多少個(gè)小循環(huán),log2 n唄, 所以他整個(gè)的時(shí)間復(fù)雜度就是n*log2 n,寫他就可以,O(log2 n*n),這個(gè)大家明確了(7)-----------------------------------------------------------------------------時(shí)間復(fù)雜度為O(n2)的二重循環(huán).int n =8,count = 0;for(int i=1;i<=n;i++){for(int j=1;j<=i;j++){count++;}
}這個(gè)是多少,仔細(xì)來看,n等于8,這個(gè)不搭理他,我們要的是找循環(huán)體,i小于等于n,i加加,j加加,j小于等于i,這個(gè)好奇怪,他的級(jí)別會(huì)是多少,這個(gè)要稍微繁瑣一下,你一定要想一下,這個(gè)for(int i=1;i<=n;i++)循環(huán)幾次,是不是n次,那里面的這個(gè)循環(huán)for(int j=1;j<=i;j++)循環(huán)了幾次,那是不確定的,因?yàn)閕等于1就循環(huán)1次,i等于2,,從1到2,i等于3,從1到3,所以你可以這么算一下,怎么算啊,當(dāng)i等于1的話,這條語句執(zhí)行1次,因?yàn)槟憧?從1到1嘛,j小于等于i嘛,當(dāng)i要是等于2的話,兩次,i等于3的時(shí)候,3次,再加上4等于1+2+3+4,當(dāng)i要是等于n的時(shí)候,j從1到n,是不是就是n次,告訴我1+2+3+4+....+n=?,這是不是就是他的完整的執(zhí)行次數(shù),稍微復(fù)雜一下,這不就是剛才效率最高的算法嗎,1+2+3+...+n=(1+n)*n/2,這是多少啊,這是時(shí)間復(fù)雜度嗎,這是時(shí)間頻度,我們以更加簡單的形式來寫一下,0.5n2+0.5n,這是時(shí)間頻度,T(n)=0.5n2+0.5n,我求的是T(n)=O(n2),最后就剩n的平方
我們現(xiàn)在通過這么幾個(gè)例子,讓大家對時(shí)間復(fù)雜度入門,第一個(gè)知道有哪些級(jí)別,第二個(gè)他大概是怎么來算的,還要明確這個(gè)概念,后面我們講什么線性表啦,講樹啦,講查詢排序,往往都是去說他的時(shí)間復(fù)雜度,因?yàn)檫@是衡量他優(yōu)劣的最直接的指標(biāo),你要明確常用的時(shí)間復(fù)雜度有多少? 我們列了一個(gè)表1. 常數(shù)階 O(1)2. 對數(shù)階 O(log2 n):你見到log2 n你就要想那個(gè)國際象棋,要米粒3. 線數(shù)階 O(n): 這個(gè)就和上面一個(gè)差別就很大了4. 線性對數(shù)階 O(n*log2 n)5. 平方階 O(n2): n的平方就是n乘以n, n大于log2 n6. 立方階 O(n3): 是不是復(fù)雜度效率更低........指數(shù)階 :效率更低,2的n次方階乘階: n的階乘 n!,誰能寫出這樣一個(gè)算法我佩服你,這個(gè)級(jí)別效率太低了,一般來說常用的復(fù)雜度,越往下時(shí)間復(fù)雜度越高,執(zhí)行效率越低,我們以后編寫程序,盡量控制一下規(guī)模,你如果要來個(gè)三重的循環(huán),那估計(jì)就是這個(gè)立方階 O(n3),我們這里又一個(gè)表當(dāng)n等于8,等于10,等于1000的時(shí)候,什么意思,如果你的級(jí)別是O(n)的話,如果n等于1000,你就執(zhí)行1000次,如果是O(log2 n),就是2的10次方,9次10次就可以了,9次和1000次的差別,如果O(1)一次就可以了,如果你的你別是O(n),執(zhí)行此時(shí)是1億次,但是如果是log2 n的話是8次就夠了,8次和1億次是什么差別講到這里我們就把時(shí)間的復(fù)雜度給大家說完了再來看一下算法的空間復(fù)雜度,空間復(fù)雜度沒有什么過多要說的吧,更多的是來計(jì)算時(shí)間復(fù)雜度,空間復(fù)雜度用S(n)來表示為什么要用S來表示,S是什么意思,是Space空間,n是問題的規(guī)模,S(n)=O(g(n)),O是最壞的情況,他也代表復(fù)雜度,這里面還有一個(gè)函數(shù),我們一起分析一下int fun(int n){int i,j,k,s;s=0;for(int i=0;i<=n;i++){for(int j=0;j<=i;j++){for(int k=0;k<=j;j++){s++;}}}return s;
}告訴我這個(gè)空間復(fù)雜度是多少,n是多少,那不確定,n可能是個(gè)無窮大的數(shù),他不確定,i,j,k,s,s等于0,開始循環(huán)了,就是這4個(gè)變量了,我們現(xiàn)在不是求時(shí)間復(fù)雜度,我們求的是空間復(fù)雜度,你覺得這段代碼要執(zhí)行,內(nèi)存里面要占多少空間,第一個(gè)變量是i,第二個(gè)變量是j,第三個(gè)變量是k,第四個(gè)變量是s,i是0,j是0,k是0,s是0,i要變成1,j要變成1,2,沒有分配額外的空間,這個(gè)i要變,k也要變,s也要變,只需要4個(gè)空間就夠了,因?yàn)槟阕儊碜內(nèi)?并沒有分配額外的空間,我有4個(gè)空間就夠了,并沒有占別的空間,S(n)=4,4個(gè)空間就夠了,我要空間復(fù)雜度呢,S(n)=O(1),空間復(fù)雜度是1,因?yàn)閚是100萬,他也是4個(gè)空間,什么情況下空間復(fù)雜度也會(huì)很高,n越大分的空間越多,比如說遞歸由于算法中臨時(shí)變量的個(gè)數(shù)與問題規(guī)模n無關(guān),所以空間復(fù)雜度為S(n)=O(1),空間復(fù)雜度分析2:void fun(int a[],int n,int k){// 數(shù)組a共有n個(gè)元素int i;if(k==n-1){for(int i=0;i<n;i++){// 執(zhí)行n次printf("%d\n",a[i]);}}else{for(int i=k;i<n;i++){// 執(zhí)行n-k次a[i] = a[i] + i*i;fun(a,n,k+1);}}}fun(a,n,k+1)這個(gè)叫什么啊,這個(gè)叫遞歸,自己調(diào)自己叫遞歸,這個(gè)算法大家已經(jīng)學(xué)過了,他要分多少空間,如果我們只是調(diào)用函數(shù)一次,這個(gè)函數(shù)如果調(diào)一次,不遞歸的話,需要3個(gè),一個(gè)n,一個(gè)k,一個(gè)i,再加一個(gè)數(shù)組a,數(shù)量是有限制的,級(jí)別還是1,如果還往下這么調(diào)呢,它會(huì)調(diào)多少次,會(huì)遞歸往下調(diào)多少級(jí)別,如果他是n個(gè)級(jí)別的話,如果遞歸n次的話就是1*n,每次調(diào)用這個(gè)函數(shù),比如棧的空間特別少,但是調(diào)n次,哪怕他調(diào)用n/2次呢,那這個(gè)n也是無窮數(shù),所以我們求這個(gè)級(jí)別的話怎么求,還是O(n)的,每調(diào)函數(shù)一次,花的空間很少,此屬于遞歸算法,每次調(diào)用本身都需要分配空間,空間很少,但是你經(jīng)不住他調(diào)的次數(shù)多,每遞歸一次都要分配一次空間,所以他的空間復(fù)雜度是O(n),那大家都記住一個(gè)結(jié)論,請問遞歸有什么缺點(diǎn),效率低下,占用空間多,那我為什么還要用遞歸,代碼簡單,思路簡單,特別的方便,航天飛機(jī)里面一般不用遞歸,為什么,實(shí)時(shí)系統(tǒng)里面不用遞歸,實(shí)時(shí)反應(yīng),占的空間多,效率還低,可能計(jì)算結(jié)果要花很多的時(shí)間,但是他代碼簡單,性能要求不是特別高的情況下,可以用遞歸來實(shí)現(xiàn),在我們后面的數(shù)據(jù)結(jié)構(gòu)里面,使用最多的一個(gè)內(nèi)容就是遞歸,很多地方樹的遍歷,圖的遍歷,折半查找,還有很多的查詢排序,都用到遞歸,下來對遞歸進(jìn)行了大量的練習(xí),因?yàn)檫f歸是我們面試的時(shí)候用的比較多的內(nèi)容,關(guān)于空間復(fù)雜度我們就簡單的說到這里記住:1. 空間復(fù)雜度比時(shí)間復(fù)雜度分析要少2. 用遞歸算法,代碼比較簡單,算法本身占的空間少,但是運(yùn)行的時(shí)候要分配比較多的空間,寫的代碼少,但是運(yùn)行是需要多次調(diào)用,占很多的空間,如果采用非遞歸算法呢,代碼可能會(huì)很長,代碼會(huì)是很復(fù)雜的代碼,代碼多了,存代碼就占的多了,運(yùn)行的時(shí)候,就像我們剛剛畫的圖一樣,運(yùn)行的時(shí)候就占的比較少
?
總結(jié)
以上是生活随笔為你收集整理的分析时间复杂度和空间复杂度(一级)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法和时间复杂度概念(一级)
- 下一篇: 线性表及其逻辑和存储结构(二级)