本系列讀書筆記參考自數(shù)據(jù)結(jié)構(gòu)與算法經(jīng)典問題解析第二版內(nèi)容,習(xí)題答案部分有誤,已勘正塘安,部分嚴(yán)格證明參考算法導(dǎo)論第三版,水平有限援奢,如有紕漏兼犯,盡請指出
基礎(chǔ)概念
數(shù)據(jù)結(jié)構(gòu)是計(jì)算機(jī)存儲和組織數(shù)據(jù)的一種特定方式,通過特定的數(shù)據(jù)結(jié)構(gòu)可以使相應(yīng)的數(shù)據(jù)處理更加有效集漾,常見的數(shù)據(jù)結(jié)構(gòu)包括:數(shù)組切黔,文件,鏈表具篇,棧纬霞,隊(duì)列,樹驱显,圖等诗芜。
根據(jù)其元素組織方式,數(shù)據(jù)結(jié)構(gòu)可分為兩種類型:
- 線性數(shù)據(jù)結(jié)構(gòu):可以按線性次序訪問元素埃疫,但它并不強(qiáng)制將所有元素連續(xù)存儲在一起(如鏈表)伏恐。主要有鏈表,棧和隊(duì)列
- 非線性數(shù)據(jù)結(jié)構(gòu):這種數(shù)據(jù)結(jié)構(gòu)的元素是以非線性次序來存儲和訪問元素的熔恢,例如樹和圖
為了簡化求解問題的過程脐湾,我們將數(shù)據(jù)結(jié)構(gòu)和相關(guān)運(yùn)算組合起來臭笆,統(tǒng)稱為抽象數(shù)據(jù)類型ADT叙淌,其包含兩個(gè)部分:數(shù)據(jù)的聲明和運(yùn)算的聲明
常用的ADT包括:鏈表秤掌,棧,隊(duì)列鹰霍,優(yōu)先隊(duì)列闻鉴,二叉樹,字典茂洒,并查集孟岛,散列表,圖等其他類型
當(dāng)定義ADT時(shí)督勺,不需要考慮其實(shí)現(xiàn)細(xì)節(jié)渠羞,僅當(dāng)需要使用它們時(shí),才考慮具體的實(shí)現(xiàn)智哀。不同的ADT類型適用于不同的場合次询,需要我們靈活應(yīng)用
算法分析的目標(biāo)在于根據(jù)運(yùn)行時(shí)間及其它的一些因素(如內(nèi)存,開發(fā)者的工作量等)來比較算法的優(yōu)劣
運(yùn)行時(shí)間分析是指當(dāng)問題的輸入規(guī)模增大時(shí)瓷叫,研究問題的處理時(shí)間是如何增加的
為了比較算法屯吊,以下是幾種客觀評價(jià)指標(biāo):
- 執(zhí)行時(shí)間:不同的計(jì)算機(jī)會呈現(xiàn)出較大差異,不是一個(gè)好的評價(jià)標(biāo)準(zhǔn)
- 執(zhí)行的語句數(shù):因?yàn)閳?zhí)行的語句和編程語言以及程序員個(gè)人的編程風(fēng)格相關(guān)摹菠,也不是一個(gè)好的評價(jià)標(biāo)準(zhǔn)
- 函數(shù)表示:假設(shè)用一個(gè)函數(shù)
表示一個(gè)算法的運(yùn)行時(shí)間盒卸,而問題的輸入規(guī)模用
表示,通過比較不同算法對應(yīng)的的
次氨,就足以比較出各種算法的優(yōu)劣
增長率是指隨著輸入規(guī)模的增加蔽介,算法運(yùn)行時(shí)間增加的速度,也就是說對于一個(gè)給定的函數(shù)煮寡,我們會忽略相對影響更小的低階因變量(當(dāng)n很大時(shí))屉佳,例如對于下式我們可以認(rèn)為:
算法分析
算法分析有如下三種類型:
- 最壞情況:定義算法最長運(yùn)行時(shí)間的輸入,這種輸入使得算法運(yùn)行最慢
- 最好情況:定義算法最短運(yùn)行時(shí)間的輸入洲押,這種輸入使得算法運(yùn)行最快
- 平均情況:提供算法運(yùn)行時(shí)間的預(yù)測值武花,此時(shí)假設(shè)輸入是隨機(jī)的,也就是說有:
在我們定義了輸入的不同類型后杈帐,我們需要對算法運(yùn)行時(shí)間的上下界和平均時(shí)間做一個(gè)準(zhǔn)確的定義
大O表示法
大O表示法給出了函數(shù)的嚴(yán)格上界体箕,我們記作
,表示當(dāng)輸入規(guī)模
很大時(shí)挑童,
的漸進(jìn)上界是
用更準(zhǔn)確的數(shù)學(xué)語言來說累铅,大O表示法定義為:
注意當(dāng)邊界只能大于(小于)而不能等于時(shí)站叼,認(rèn)為邊界是漸進(jìn)的但不是緊確的娃兽,也就是滿足下式
此時(shí)我們稱是
的一個(gè)漸進(jìn)非緊確上界
顯然是指所有與
具有相同增長率或比起增長率小的函數(shù)的集合尽楔,例如下圖
但使用小o表示法投储,則不包含例如內(nèi)的函數(shù)
表示法
與大O表示法類似第练,表示法給出
的嚴(yán)格下界,記作
玛荞,表示輸入規(guī)模
很大時(shí)娇掏,
的漸進(jìn)下界是
用更準(zhǔn)確的數(shù)學(xué)語言來說,表示法定義為:
在使用中婴梧,我們需要盡可能求出滿足條件的最大階的
同樣的當(dāng)滿足下式
此時(shí)我們稱是
的一個(gè)漸進(jìn)非緊確下界
例如客蹋,則
是正確的,而
也是正確的讶坯,
是錯(cuò)誤的
表示法
表示法決定了算法的時(shí)間增長率上界和下界是否相同浮还,如果大O表示法與
表示法給出的結(jié)果是一樣的,那么
表示法也會給出相同的結(jié)果闽巩。而對于一個(gè)給定的函數(shù)钧舌,如果它增長率的上界和下界是不同的,那么
表示法需要通過分析所有可能的時(shí)間復(fù)雜度涎跨,然后得出平均情況下的結(jié)論(例如快速排序的平均情況洼冻,參見第十章)
表示法的數(shù)學(xué)含義:
- 對于函數(shù)
,如果存在常數(shù)
使得
隅很,那么有
用圖示表示以上表示法如下:
小結(jié):
一些通用的計(jì)算規(guī)則:
漸進(jìn)表示法的基本性質(zhì):
一些常用的數(shù)學(xué)公式:
分治法定理
分治法是指把一個(gè)問題劃分為多個(gè)子問題,每個(gè)子問題是原問題的一部分叔营,然后執(zhí)行一些額外的工作來計(jì)算最后的答案屋彪,例如歸并排序中,將原問題分為兩個(gè)子問題绒尊,每個(gè)子問題都是原問題規(guī)模的一半畜挥,然后用的額外工作完成歸并,可以用下式表示
我們把這種分治法思想推廣婴谱,如果一個(gè)問題可以通過以下遞歸形式表示
則有如下幾種情況:
- 當(dāng)
時(shí),
- 當(dāng)
時(shí)
a. 如果谭羔,
b. 如果华糖,
c. 如果,
- 如果
a. 如果瘟裸,
b. 如果客叉,
這就是分治法的主定理,下面是一些使用主定理的例子
在主定理之上,還有一些變形:
變形1:當(dāng)對于常數(shù)和
有
如果的時(shí)間復(fù)雜度是
兼搏,則
變形2:,則其復(fù)雜度為
猜測的方法
平攤分析
下面是一些典型習(xí)題及其解答
上圖中F(2)還需要分為F(1)和F(0)向族,樹有N層
解答有誤,應(yīng)該是假設(shè)是一顆滿二叉樹棠绘,則葉子節(jié)點(diǎn)少于(事實(shí)上件相,依然屬于
階)
時(shí)間復(fù)雜度:
空間復(fù)雜度:
也就是說
上式中注意省略掉這一步