《數據結構與算法分析》5000字縮寫(上)

《數據結構與算法分析》5000字縮寫(上)

    4月7日買起來看,前幾天纔看完。這可以說明很多問題,比如,學習很緊張,沒有時間;書本身很好,很有看頭;看書看得很細心,很有耐心。
    打算大致寫一下書裏的內容。
    Data Structures and Algorithm Analysis in C, Second Edition,機械工業出版社。封面很醜,一個黑底版,上面有些大理石花紋,正中間生硬的擺一個原版封面,同樣醜。一共12章,近400頁。
    400多頁是很多的。我們必須要“把厚書讀薄”,厚的變薄的,薄的變一頁,一頁變一行,一行變成一個字。因此,我要在有限的字數內把整本書說完。

    算法分析,就是複雜度的問題。複雜度只算“最要命的”,比如,執行n^2的算法前來個快排根本不拖速度,n^2多的都豁出去了不在乎區區一個nlogn。書裏對複雜度進行了嚴格的定義,包括O()、o()、Θ()、Ω()四種符號。簡單地說,O(n^2)就是頂破天了搞個n^2次;o(n^2)就是天花板不到n^2,比n^2矮一點(比如希爾排序就是o(n^2),因爲它再倒黴也達不到n^2);Ω(n^2)就是說某個算法隨便怎麼至少都要耗費n^2,比如所有基於比較的排序都是Ω(nlogn);Θ(n^2)就是說它即是O(n^2)又是Ω(n^2),被天花板和水泥地夾在中間了,動不了了,就是它了。這裏面有一個經典的例子,就是最大子序列(找數列中連續一段數之和最大)的四種算法,複雜度分別爲O(n^3)、O(n^2)、O(nlogn)和O (n)。這書一個特色在於,對每種數據結構都有嚴格的算法複雜度證明,這往往是看上去最頭痛的部分。

    表、棧和隊列是三個基本的數據結構。說穿了表就是把數據找起來排排坐吃果果,找什麼東西都來把整個隊伍找一遍。棧就是一個桶,先放進去的先拿出來,它下面本來有的東西要等它出來之後才能出來,就好像你看到了一個醜人不可能今天的中飯還沒吐出來就先把早飯吐出來了。棧是拿來模擬多個過程的調用的(比如遞歸),實際點的用途就是表達式計算。隊列好比堵車,先進去的先出來。先進隊先買票,不能插隊。常拿來實現廣搜。

    樹,是一種植物,有很多枝枝丫丫。不同的是這裏的樹是倒着的,樹枝朝下長。最上面叫根,尖尖的地方叫樹葉,生出樹葉的是他爸,他爸生的是他兒子。不管是根是樹葉還是兒子還是兒子他爸都叫節點。我們常常把數據儲存在節點上,並且以後還要不斷地插入、改變和刪除數據。
    二叉樹就是每個分叉的地方最多分兩個岔,而且還分得清左右。二叉查找樹就是說把數據存在節點上,而且左邊的都比他爸小,右邊的都比他爸大,以後要找哪個數就可以只找其中的一邊,一半一半地扔掉。在二叉查找樹裏也可以插入一個數,刪掉一個數(只有一個兒子好辦,有兩個就把右邊的最小的一個拿來替代這個),找最小的數(一直往左走),找最大的數(一直往右走),但是容易搞着搞着的樹就變畸形了,比如說左邊猛起長右邊萎縮導致以後往左邊走要走很久。我們就需要一種方法來讓樹左右差不多一樣多而且左邊的值仍然比右邊的小。事實上這種方法已經找到了,而且不只一種方法,而是一卡車的方法,比如AVL、Splay、紅黑樹、Treap等。幾種方法都靠一個叫“旋轉”的技巧,就是把幾個節點怎麼個一轉,左邊的就跑到右邊去了一點。看下面這個圖你就明白了。

         ①                   ②
        /  /      旋轉       /  /
      ②   ZZ    ------>    XX  ①
     /  /                      /  /
    XX  YY                    YY  ZZ


這樣一來左邊就少了,如果左邊的XX本來很多的話就可以往上提一層從而平衡。同樣地,右邊多了反過來做就是了。這只是最簡單的“單旋轉”,事實上還有很多其它的較複雜的旋轉方法。Splay樹就是把剛纔訪問過的節點轉啊轉啊轉啊轉轉到最頂上去,Treap就是每個節點附加一個隨機的數,隨時通過旋轉保持兒子的這些隨機數比他爸大,其餘的有點複雜。這些方法都能使二叉查找樹相對地平衡一些,防止畸變導致的時間浪費。
    B-樹和二叉查找樹有兩個不同,一個是節點不存數據,數據全在樹葉子上,二個是它不一定是二叉。數據仍然左邊小右邊大方便查找。每個節點最多的兒子數有限制,最多三叉的叫2-3樹,最多四叉的叫2-3-4樹。因爲只有樹葉上有數據,所以可以遞歸地用分裂的方法處理新插入後出現的分叉比規定的最多的兒子個數時還多的情況。比如,2-3樹中如果哪裏分了四個岔,就把它重新分成兩個兩個的岔。我們還規定,除了根以外,每個節點最少的兒子數是規定的最多兒子數的一半,除不盡取上整。容易想到,刪除的話可以把插入時的分裂反過來做,什麼時候只剩一個兒子了就和旁邊的合併起來。

    Hash表又叫散列表,一般用於判斷有沒有重複。比如我想找我們班有沒有兩個一天生的,我們不必每兩個人都來比較一次,而是準備一個年曆,讓人一個一個上去在他的生日那天那裏畫一個圈,如果誰要畫圈時發現那裏已經有一個圈了,就找到了一對。這個很簡單,不說了。
    那天班上流行一個心裏測試,當時我還真發現了一個和我一天生的,女的。

Matrix67原創
做人要厚道 轉帖請註明出處 

 
發佈了2 篇原創文章 · 獲贊 13 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章