《數(shù)據(jù)結(jié)構(gòu)與算法分析》筆記

一:數(shù)據(jù)結(jié)構(gòu)概論

  • 在數(shù)據(jù)結(jié)構(gòu)中數(shù)據(jù)分為兩種關(guān)系,一種時線性誓沸,一種是非線性
  • 線性關(guān)系梅桩,比如一張學(xué)生登記表。
  • 非線性關(guān)系拜隧,比如文件夾是樹型關(guān)系摘投,比如計算機網(wǎng)絡(luò)是圖關(guān)系。

數(shù)據(jù)結(jié)構(gòu)包括:

  • 數(shù)據(jù)的存儲
    • 物理結(jié)構(gòu):數(shù)據(jù)在計算機內(nèi)的存儲表示
  • 數(shù)據(jù)之間的關(guān)系
    • 邏輯結(jié)構(gòu):數(shù)據(jù)之間的邏輯關(guān)系虹蓄。分為兩種一種是順序存儲結(jié)構(gòu)犀呼,一種是非順序存儲結(jié)構(gòu)。順序結(jié)構(gòu)一般用一維數(shù)組體現(xiàn)數(shù)據(jù)之間的關(guān)系薇组。非順序存儲結(jié)構(gòu)一般采用指針實現(xiàn)數(shù)據(jù)之間的關(guān)系外臂,包括鏈式存儲結(jié)構(gòu)和散列結(jié)構(gòu),索引存儲結(jié)構(gòu)等律胀。鏈式存儲利用指針直接表示數(shù)據(jù)元素之間的關(guān)系宋光。散列結(jié)構(gòu)是根據(jù)節(jié)點的關(guān)鍵字貌矿,利用散列函數(shù)直接計算出該節(jié)點的存儲地址。索引存儲結(jié)構(gòu)是在存儲節(jié)點信息的同時罪佳,還建立附加的索引表逛漫。索引結(jié)構(gòu)分為稠密索引和稀疏索引。
  • 數(shù)據(jù)的操作赘艳。在各種結(jié)構(gòu)上的算法酌毡。

數(shù)據(jù)類型:一個值的集合以及在這些值上定義的一組操作的總稱。

算法特征:

  • 正確性
  • 確定性
  • 有窮性
  • 輸入
  • 輸出
    效率和低存儲量兩者通常情況下是矛盾的蕾管。

二:線性表

線性表定義:每個數(shù)據(jù)元素最多只有一個直接前趨枷踏,每個數(shù)據(jù)元素最多只有一個直接后繼,只有第一個數(shù)據(jù)元素沒有直接前趨掰曾,最后一個數(shù)據(jù)元素沒有直接后繼旭蠕。

線性表的存儲分為順序存儲和非順序存儲。

  • 順序存儲也稱為向量存儲或一維數(shù)組存儲旷坦。特點是邏輯關(guān)系上相鄰的兩個元素在物理位置上也相鄰掏熬,隨機存取元素簡單,插入刪除會造成大量數(shù)據(jù)移動秒梅。線性表的順序存儲的情況下插入和刪除算法的時間復(fù)雜度為o(n);求表長以及取第i個元素的時間復(fù)雜度為o(1);

  • 線性表的鏈式存儲旗芬,不要求邏輯上相鄰的數(shù)據(jù)元素在物理位置上也相鄰。由于不要求物理位置上也相鄰番电,那么每個節(jié)點對象包含兩個元素,一個是當(dāng)前值辆琅,一個是指向下一個節(jié)點的地址漱办。如果插入某個值,那么將插入的值的節(jié)點指向之前的后繼婉烟,之前的指向下一個節(jié)點指向這個插入的節(jié)點即可娩井。

    • 尾插入法。需要一個head指針指向頭部似袁,一個tail指針指向尾部洞辣,其他的地址都保存在前趨的next中。
    • 頭插入法昙衅。不需要tail指針指向尾部扬霜,只是需要不斷修改head頭指針。

鏈式存儲的查找比較麻煩而涉,要按照順序一個一個查著瓶,求表長也如此。單向鏈表啼县,頭節(jié)點至關(guān)重要材原。循環(huán)鏈式存儲沸久,是指最后一個元素的next指向頭部。這樣以來余蟹,就可以查找每個元素的前趨卷胯。

雙向鏈表是在每個節(jié)點的值和next兩個元素的基礎(chǔ)上,再加一個prior威酒,用來保存指向前趨的指針窑睁。當(dāng)然還有雙向循環(huán)鏈表。

三:棧和隊列

兩種特殊的線性表兼搏。

棧:先進后出卵慰。限制只有棧頂才可以操作。每次pop刪除的總是最新元素佛呻,每次push壓入的元素也總是最新元素裳朋。

實現(xiàn)棧的方式:順序棧和鏈式棧

順序棧:入棧是在線性表的頭部插入元素,出棧是在線性表的頭部刪除一個元素吓著。這樣效率不高鲤嫡,時間代價為o(n)。如果是在線性表的尾部作為棧頂绑莺,插入刪除元素暖眼,那么時間代價為o(1),效率高纺裁。

鏈式棧:單向鏈表存儲棧诫肠。操作一般在頭部。

順序棧和鏈式棧比較:當(dāng)需要堆棧共享時欺缘,順序椂霸ィ可以使用一個數(shù)組存儲兩個棧, 數(shù)組的兩端作為兩個棧各自的棧低谚殊,中間部分為共享區(qū)域丧鸯。這樣的情況適合兩個棧有相反的需求時,此消彼長的情況嫩絮。鏈式棧是每個節(jié)點多了一個指針域的開銷丛肢。

隊列:先進先出。只需要操作線性表的兩端剿干。一端只能進入蜂怎,另一端只能出。隊尾進置尔,隊首出派敷。有順序存儲和鏈式存儲兩種。隊列假溢出是因為隊首指針確定導(dǎo)致的,就是被刪除的元素空間無法被重復(fù)利用篮愉「郑可以讓隊首和隊尾的指針循環(huán)起來就可以,就是將元素存儲在循環(huán)向量中试躏。

基本運算:
判斷隊空

隊列初始化

判斷隊滿

入隊元素

出隊元素

取隊首元素

順序隊列:必須用一個向量空間來存放元素猪勇。設(shè)置front和rear分別來指示隊首和隊尾的位置。

循環(huán)隊列:就是將元素存儲在循環(huán)向量中颠蕴。

鏈式隊列:

四:數(shù)組和廣義表

矩陣存儲分為行優(yōu)先和列優(yōu)先兩種泣刹。

矩陣壓縮存儲,是針對特殊矩陣隊存儲犀被,只存儲其元素一部分椅您,另一部分通過相應(yīng)的算法計算出來。這樣的矩陣包括對稱矩陣寡键,稀疏矩陣和三角矩陣掀泳。

  • 稀疏矩陣:矩陣中有多數(shù)為零的值。到底這個數(shù)占了全部數(shù)的多少位稀疏矩陣呢西轩?假設(shè)有m行n列矩陣员舵,有t個非零元素,那么滿足(t+1)*3<=m*n即可

廣義表是線性表的擴展藕畔。元素包括

  • 原子元素
  • 可以再分的元素

如果所有元素都是原子元素則是線性表马僻。如果有可以再分的元素,也就是子表注服,則是廣義表韭邓。廣義表含有元素的個數(shù)稱為廣義表的長度,廣義表中含有括號對數(shù)稱為廣義表的深度溶弟,也就是層女淑。


五:樹

非線性結(jié)構(gòu)。樹的遞歸定義:樹是由根節(jié)點和若干棵子樹構(gòu)成的可很。

一個節(jié)點的子樹個數(shù)稱為該節(jié)點的度诗力。

度為零的節(jié)點稱為葉子或終端節(jié)點凰浮。不為零的為分支節(jié)點我抠。除根節(jié)點之外的稱為內(nèi)部節(jié)點。

一棵樹中節(jié)點度最大的值稱為該樹的度袜茧。

二叉樹:或者為空菜拓,或者由一個根節(jié)點加上兩棵左右互不交叉的子樹構(gòu)成。

  • 滿二叉樹:每個父親都有兩個兒子笛厦。
  • 完全二叉樹

二叉樹的順序存儲:只存儲節(jié)點的值纳鼎,不存儲節(jié)點之間的邏輯關(guān)系


二叉樹的鏈接存儲:每個節(jié)點由數(shù)據(jù)域和指針域兩部分組成。指針域有兩個,一個指向父親贱鄙,一個指向兒子劝贸。


二叉樹遍歷,包括前中后三序遍歷逗宁,以及層次遍歷映九。

當(dāng)我們遍歷完二叉樹,就形成一個線性序列瞎颗,于是就有了唯一的前趨和后繼節(jié)點件甥。

線索二叉樹,就是為了解決尋找前趨和后繼的哼拔。每個鏈接節(jié)點有五個變量引有,通常樹都是鏈式存儲。

將一棵樹轉(zhuǎn)為二叉樹的方法:

  • 樹中所有相鄰兄弟之間加一條連線倦逐。
  • 對樹中每個節(jié)點譬正,只保留它與第一個兒子節(jié)點之間的聯(lián)系,刪除它與其他兒子的連線僻孝。
  • 以樹的根節(jié)點為軸旋轉(zhuǎn)导帝。
  • 這樣的旋轉(zhuǎn)可以證明是唯一的。而且過程是可逆的穿铆。


將二叉樹還原為普通樹的方法:


樹的遍歷分為先根遍歷和后根遍歷您单。

森林的遍歷分為前序遍歷和中序遍歷。

哈夫曼樹荞雏,也是二叉樹虐秦。這種二叉樹的帶權(quán)路徑長度最小。并且每個權(quán)值都是葉子節(jié)點凤优。
帶權(quán)路徑長度為根節(jié)點到該節(jié)點之間的路徑長度與該節(jié)點的值的乘積悦陋。該節(jié)點的值,是我們?nèi)藶橹付ǖ摹?br> 路徑長度是層數(shù)減1.根節(jié)點為第一層筑辨。


六:圖

圖是非線性結(jié)構(gòu)俺驶。圖中任何兩個頂點都可能有關(guān)聯(lián),頂點間的關(guān)系是多對多點關(guān)系棍辕。圖的每個節(jié)點有任意多個前趨和后繼暮现。圖分為有向圖和無向圖。帶權(quán)的圖稱為網(wǎng)楚昭。網(wǎng)分為有向網(wǎng)和無向網(wǎng)栖袋。

1:圖的存儲結(jié)構(gòu)

圖的鄰接矩陣表示法和鄰接表表示法。
鄰接矩陣抚太,行與列分別表示各個頂點塘幅。1表示有邊昔案,0表示沒有邊。比如第一行第二列是1电媳,則表示頂點1到頂點2有邊踏揣。第三行第四列是1,則表示頂點3到頂點4有邊匾乓。這是有向圖呼伸。如果是無向圖的話,那么矩陣是對稱的钝尸,就是說如果第三行第四列是1括享,那么第四列第三行也是1,因為頂點3和頂點4的邊沒有方向珍促。

鄰接表:是圖的一種鏈式存儲結(jié)構(gòu)铃辖。先建立一個鏈表存儲每個頂點。每個頂點有兩個域猪叙,鄰接點域和指針域娇斩。鄰接點域存序號,指針域指向邊的表節(jié)點穴翩。邊表是存儲頂點與鄰接點具有邊關(guān)系的表犬第,每個節(jié)點也有兩個域,指針域指向下一個與鄰接表節(jié)點具有邊關(guān)系的頂點芒帕。比如頂點1與頂點2歉嗓,3都有邊。那么頂點1在鄰接表中的指針域指向邊表的頂點2的位置背蟆。邊表中頂點2的指針域指向與頂點1有邊的頂點3的位置鉴分。

2:圖的遍歷

圖的深度優(yōu)先遍歷和廣度優(yōu)先遍歷

  • 深度優(yōu)先遍歷:遞歸訪問頂點,直到某個頂點沒有未被訪問的頂點為止带膀,開始訪問它的前趨志珍。如果前趨是最開始訪問的那個頂點,就結(jié)束遍歷垛叨。

  • 廣度優(yōu)先遍歷:從最開始的訪問點出發(fā)伦糯,訪問與它鄰接的所有點,再從這些鄰接點出發(fā)訪問它們的鄰接點嗽元。直到所有頂點均被訪問為止敛纲。

3:最小生成樹

克魯斯卡爾算法。普里姆算法

4:最短路徑和拓撲排序

最短路徑:迪卡斯特拉算法

拓撲排序:從網(wǎng)中旋轉(zhuǎn)一個入度為0的頂點并輸出还棱。也就是沒有其它頂點指向這個頂點载慈,只有這個頂點指向其它頂點惭等。從網(wǎng)中刪除此頂點及其所有出邊珍手。如此循環(huán)。拓撲排序解決的是各個頂點的依賴關(guān)系的有序數(shù)列。

七:排序

排序的穩(wěn)定性是根據(jù)需要排序的元素中的關(guān)鍵字如果有相等的情況琳要,那么這些相等關(guān)鍵字的元素如果排序前后的相對位置不變就是穩(wěn)定的寡具,如果這些相等關(guān)鍵字的元素相對位置發(fā)生了改變,就是不穩(wěn)定的稚补。
排序過程中是否涉及數(shù)據(jù)的內(nèi)外存交換可以將排序分為:

  • 內(nèi)部排序

    • 插入排序童叠。將待排序的數(shù)組中元素,一個一個地插入到有序數(shù)組當(dāng)中课幕。
      • 直接插入排序厦坛。穩(wěn)定。正序是o(n)乍惊,反序和隨機是o(n*n);
      • 希爾排序杜秸。不穩(wěn)定。在直接插入排序的基礎(chǔ)上進行分組插入润绎。
    • 選擇排序撬碟。每一趟從待排序的記錄中選擇關(guān)鍵字最小的紀錄順序放在排好序的子文件最后。
      • 直接選擇排序莉撇。不穩(wěn)定呢蛤。o(n*n)
      • 堆排序。
    • 交換排序棍郎。兩兩比較待排序記錄的關(guān)鍵字其障,發(fā)現(xiàn)兩個紀錄的次序相反時就進行交換。
      • 冒泡排序涂佃。正序是o(n)静秆。最壞是o(n*n)。穩(wěn)定巡李。排序過程中交替改變掃描方向抚笔,改進不對稱性。
      • 快速排序侨拦。不穩(wěn)定殊橙。平均時間復(fù)雜度o(nlgn)
    • 歸并排序
    • 分配排序
  • 外部排序

    • 合并排序
    • 直接合并排序法

八:查找

1:順序查找。適用于線性表的順序結(jié)構(gòu)狱从,也適用于線性表的鏈式存儲結(jié)構(gòu)膨蛮。但是鏈式存儲結(jié)構(gòu)需要從第一個節(jié)點開始掃描季研。
2:二分查找与涡。屬于靜態(tài)查找,因為如果該表要是還需要修改氨肌,那么就很費時。要求線性表是有序的卿叽,并且要用向量作為表的存儲結(jié)構(gòu)考婴。二分查找不會超過樹的深度催烘,但是由于需要有序颗圣,因此也費時在岂。二分查找只能用于順序結(jié)構(gòu)。鏈式結(jié)構(gòu)需要用順序查找易茬。因為二分查找需要線性表可以隨機存取抽莱。因為二分查找需要隨機讀取一半的位置食铐,一半的一半的位置僧鲁。寞秃。春寿。
3:分塊查找。比如給一個學(xué)號要在一個學(xué)校中查找谢床。我們需要維護一個數(shù)組用來存放有序的的班級信息。通過二分查找找到班級所在的塊之后,再通過順序查找來查找班級中的學(xué)號覆履。分塊查找是順序查找和二分查找的結(jié)合费薄。需要多維護一個有序索引數(shù)組楞抡。
4:二叉排序樹簿寂。動態(tài)查找表效率高比藻。每個節(jié)點的左邊子元素的值小于該節(jié)點棠隐,右子元素的值大于該節(jié)點暂幼。二叉排序樹最壞的情況是形成一個單支樹,最好的情況是勻稱败潦。
5:B樹劫扒,用來對磁盤等外部存儲進行查找。B樹幾乎替代了除散列方法意外的所有大型文件查找疮胖。
6:散列表澎灸。建立關(guān)鍵字與地址之間的關(guān)系遮晚,通過對元素直接尋址來查找县遣。兩個不同的關(guān)鍵字汹族,由于散列函數(shù)值不同顶瞒,而被映射到同一個低智商榴徐,稱為沖突坑资。

九:動態(tài)存儲管理

動態(tài)內(nèi)存分區(qū)常用算法:

最先適配法(nrst-fit):按分區(qū)在內(nèi)存的先后次序從頭查找袱贮,找到符合要求的第一個分區(qū)進行分配攒巍。該算法的分配和釋放的時間性能較好窑业,較大的空閑分區(qū)可以被保留在內(nèi)存高端常柄。但隨著低端分區(qū)不斷劃分會產(chǎn)生較多小分區(qū)西潘,每次分配時查找時間開銷便會增大喷市。

下次適配法(循環(huán)首次適應(yīng)算法 next fit):按分區(qū)在內(nèi)存的先后次序品姓,從上次分配的分區(qū)起查找(到最后{區(qū)時再從頭開始}腹备,找到符合要求的第一個分區(qū)進行分配植酥。該算法的分配和釋放的時間性能較好,使空閑分區(qū)分布得更均勻漂羊,但較大空閑分區(qū)不易保留。

最佳適配法(best-fit):按分區(qū)在內(nèi)存的先后次序從頭查找耻瑟,找到其大小與要求相差最小的空閑分區(qū)進行分配。從個別來看淤毛,外碎片較小瞬项;但從整體來看囱淋,會形成較多外碎片優(yōu)點是較大的空閑分區(qū)可以被保留妥衣。

最壞適配法(worst- fit):按分區(qū)在內(nèi)存的先后次序從頭查找税手,找到最大的空閑分區(qū)進行分配芦倒”铮基本不留下小空閑分區(qū)器钟,不易形成外碎片俱箱。但由于較大的空閑分區(qū)不被保留狞谱,當(dāng)對內(nèi)存需求較大的進程需要運行時跟衅,其要求不易被滿足掰读。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叭莫,隨后出現(xiàn)的幾起案子蹈集,更是在濱河造成了極大的恐慌,老刑警劉巖雇初,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拢肆,死亡現(xiàn)場離奇詭異,居然都是意外死亡靖诗,警方通過查閱死者的電腦和手機郭怪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刊橘,“玉大人鄙才,你說我怎么就攤上這事攒庵∥获茫” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵装哆,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任烦绳,我火速辦了婚禮躺孝,結(jié)果婚禮上于个,老公的妹妹穿的比我還像新娘羽氮。我一直安慰自己,他們只是感情好叼耙,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布拦惋。 她就那樣靜靜地躺著软能,像睡著了一般跋核。 火紅的嫁衣襯著肌膚如雪刻伊。 梳的紋絲不亂的頭發(fā)上蛾茉,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音,去河邊找鬼音诫。 笑死,一個胖子當(dāng)著我的面吹牛港粱,可吹牛的內(nèi)容都是我干的击吱。 我是一名探鬼主播淋淀,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼朵纷,長吁一口氣:“原來是場噩夢啊……” “哼搅吁!你這毒婦竟也來了界拦?” 一聲冷哼從身側(cè)響起聚凹,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孝常,沒想到半個月后旗们,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡构灸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年上渴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喜颁。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡稠氮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出半开,到底是詐尸還是另有隱情隔披,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布寂拆,位于F島的核電站奢米,受9級特大地震影響芥炭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恃慧,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一园蝠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧痢士,春花似錦彪薛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至城侧,卻和暖如春易遣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嫌佑。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工豆茫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屋摇。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓揩魂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親炮温。 傳聞我的和親對象是個殘疾皇子火脉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容