《大話資料結構》筆記
第1章 資料結構緒論
資料結構:是相互之間存在一種或多種特定關係的資料元素的集合。
邏輯結構是面向問題的,而物理結構就是面向計算機的,其基本的目標就是將資料及其邏輯關係儲存到計算機的記憶體中。
邏輯結構:實質是指資料物件中資料元素之間的相互關係。
1.集合結構(沒關係)
2.線性結構(一對一)
3.樹形結構(一對多)
4.圖形結構(多對多)
物理結構:是指資料的邏輯結構在計算機中的儲存形式。
1.順序儲存結構:是把資料元素存放在連續的儲存單元裡,其資料間的邏輯關係和物理關係是一樣的。(排隊站位)。
順序儲存結構的3個屬性:儲存空間的起始位置,線性表的最大儲存容量,線性表的當前長度。
2.鏈式儲存結構:是把資料元素存放在任意的儲存單元裡,這組儲存單元可以是連續的,也可以是不連續的。(銀行拿號排隊)。用指標(號)存放資料元素地址,通過地址就可以找到相關聯資料元素的位置。
第2章 演算法
ps:很遺憾以前沒明白“演算法是程式的靈魂”這句話......又黑又重又貴的《演算法導論》拿來瞻(dian)仰(dong xi)了。
演算法:是解決特定問題求解步驟的描述,在計算機中表現為指令的有限序列,並且每條指令表示一個或多個操作。
演算法特性:
1.輸入輸出
2.有窮性
3.確定性
4.可行性
演算法設計的要求:
1.正確性
2.可讀性
3.健壯性
4.時間效率高
5.儲存記憶體底
常見的時間複雜度:O(1)<O()<O(n)<O(n)<O()<O()<O()<O(n!)<O()
第3章 線性表
線性表(List):零個或多個數據元素的有限序列,得是相同資料型別,一個元素只有一個前驅元素(除第一個)和一個後繼(除最後一個)元素。(人根據號碼排隊,不能用書包給別人佔位)。在較複雜的線性表中,一個數據元素可以由若干個資料項組成。(學號,姓名,性別,手機號碼,家庭地址)。
線性表的順序儲存結構:指的是用一段地址連續的儲存單元一次儲存線性表的資料元素。
陣列的長度是存放線性表的儲存空間的長度,儲存分配後這個量一般是不變的。
線性表的長度是線性表中資料元素的個數,隨著線性表插入和刪除操作的進行,這個量是變化的。
在任意時刻,線性表的長度(來的人數)<陣列的長度(佔的作為數)
插入:火車站排隊買票,如果插隊則這個人後面的人都要往後移動。
刪除:火車站排隊買票,如果有人走了,這個人的後面的人都將往前移動。
線性表的順序儲存結構優點:
1.無須為表示表中元素之間的邏輯關係而增加額外的儲存空間
2.可以快速的存取表中任一位置元素
線性表的順序儲存結構缺點:
1.插入和刪除操作都需要移動大量元素
2.當線性表長度變化較大時,難以確定儲存空間的容量
3.造成儲存空間的“碎片”
線性表的鏈式儲存結構:n個節點(ai的儲存影像)鏈結成一個連結串列,即線性表(a1,a2,a3,......,an)的鏈式儲存結構,因此為此連結串列的每個節點中只包含一個指標域,所以叫單鏈表。單鏈表通過每個節點的指標域將線性表的資料元素按其邏輯次序連結在一起。
節點:由存放資料元素的資料域和存放後繼節點地址的指標域組成。
假設p是指向線性表第i個元素的指標:
p->data的值是一個數據元素,即節點ai的資料域。
p->next的值是一個指標,指向i+1個元素,即指向ai+1。
連結串列中第一個節點的儲存位置叫做頭指標。頭節點(可存線性表+頭指標,其資料域一般沒什麼意義)和第一個節點(第一個元素+指向下一個元素的位置)不一樣。最後一個節點(最後一個元素+null)。
3.11單鏈表
單鏈表的插入:s->next=p->next;p->next=s。(順序一定不能反)
單鏈表的刪除:p->next=p->next->next 即 q=p->next;p->next=q->next。
對於插入或者刪除資料越頻繁的操作,單鏈表的效率優勢越是明顯。
3.12靜態連結串列
3.13迴圈連結串列
將單鏈表中終端節點的指標端由空指標改為指向頭節點,就使整個單鏈表形成一個環。
3.14雙向連結串列
在單鏈表的每個節點中,再設定一個指向其前驅節點的指標域。
第4章 棧與佇列
ps:在上完資料結構課程,我就只記得棧和佇列這兩個,慚愧......
棧是限定僅在表尾(指的是棧頂而不是棧底)進行插入和刪除操作的(一種特殊的)線性表(事先確定儲存空間大小)。
佇列是隻允許在一端進行插入操作,而在另一端進行刪除操作的線性表。
允許插入和刪除的一端稱為棧頂(top),另一端稱為棧底(button)。不包含任何資料元素的棧稱為空棧。棧又稱為後進先出(Last In First Out)的線性表。
棧的插入操作:稱為進棧,壓棧,入棧。
棧的刪除操作:稱為出棧,彈棧
棧的應用:瀏覽器上面的後退鍵,word、photoshop的撤銷鍵。遞迴。四則運算表示式求值。
遞迴:一個直接呼叫自己或者通過一系列呼叫的語句間接的呼叫自己的函式稱為遞迴函式。
思考:如何用棧實現佇列?兩棧共享空間。
棧的順序儲存結構:(和線性表差不多)
棧的鏈式儲存結構:(和線性表差不多)
迭代和遞迴的區別:迭代使用的是迴圈結構,遞迴使用的是選擇結構。
逆波蘭演算法(RPN):不需要括號的字尾表達法。
字尾表示式:所有的符號都是在要運算數字的後面出現的。
將字尾表示式進行運算得出結果(棧用來進出運算的數字):
規則:從左到右遍歷表示式的每個數字和符號,遇到數字就進棧,遇到是符號,就將處於棧頂的兩個數字出棧,進行運算,運算結果出棧,一直到最終獲得結果。
中綴表示式轉字尾表示式(棧用來進出運算的符號):
標準四則勻速那表示式叫做中綴表示式。
規則:從左到右遍歷中綴表示式的每個數字和符號,若是數字就輸出,即成為字尾表示式的一部分;若是符號,則判斷其與棧頂符號的優先順序,是右括號或優先順序不高於棧頂符號(乘除優先加減)則棧頂元素依次出棧並輸出,並將當前符號進棧,一直到最終輸出字尾表示式為止。
佇列是一種先進先出(First In First Out)的的線性表。允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。
佇列的應用:電腦假死的時候,滑鼠點了很多下都沒有反應,等到電腦活過來了,然後剛才的操作全部執行一遍;顯示器上筆記本上的輸出。
為了避免當只有一個元素時,隊頭和隊尾重合使處理變得麻煩,所以引入兩個指標,front指標指向隊頭元素,rear指標指向隊尾元素的下一個位置,這樣當front等於rear時,此佇列不是還剩一個元素,而是空佇列。
把佇列這種頭尾相接的順序儲存結構稱為迴圈佇列。
佇列滿的條件:(rear+1)%QueueSize==front
計算佇列長度公式:(rear-front+QueueSize)%QueueSize
佇列的鏈式儲存結構,其實就是線性表的單鏈表,只不過它只能尾進頭出而已。
第5章 串
串(String)是由零個或多個字元組成的有限序列,又名字串。
空串和空格串的區別
子串和主串的區別
串的順序儲存結構:是用一組地址連續的儲存單元來儲存串中的字元序列。按照預定義的大小,為每個定義的串變數分配一個固定長度的儲存區。一般是用定長陣列來定義。一般用”\0“來表示字串的終結。
串的鏈式儲存結構:和線性表相似,但由於串結構的特殊性,結構中每個元素資料是一個字元,如果也簡單的應用連結串列儲存串值,一個節點對應一個字元,就會浪費很大的空間,因此,一個節點可以存放一個字元,也可以考慮存放多個字元。
樸素的模式匹配演算法(效率低)
KMP模式匹配演算法(效率高)(看不懂!!!)
移動位數 = 已匹配的字元數 - 對應的部分匹配值
第6章 樹
樹:數(Tree)是n(n>=0)個節點的有限級。n=0時稱為空樹。在任意一顆非空樹種:(1)有且僅有一個特定的稱為跟(Root)的節點;(2)當n>1時,其與節點可分為m(m>0)個互不相交的有限集T1,T2,......,Tm,其中每個集合本身又是一棵樹,並且稱為根的子樹(Sub Tree)。
結點的分類:根節點,內部節點,葉節點或終端節點。
結點間的關係:雙親,兄弟,子孫。
樹的儲存結構表示法:
1.雙親表示法:假設以一組連續空間儲存樹的節點,同時在每個節點中,附設一個指示器指示其雙親節點在陣列中的位置。
下標 |
data:資料域,儲存節點的資料資訊 |
parent:指標域,儲存該節點的雙親在陣列中的下標 |
firstchild |
下標 |
data:資料域,儲存節點的資料資訊 |
parent:指標域,儲存該節點的雙親在陣列中的下標 |
rightsib |
2.1孩子表示法(指標域的個數就等於樹的度數,取最大度):由於樹中每個節點可能有多顆子樹,可以考慮多重連結串列,即每個結點有多個指標域,其中每個指標指向一顆子樹的根結點,這個叫多重連結串列表示法。
缺點:由於各結點的度相差很大時,非常浪費空間。
2.1孩子表示法(每個結點指標域的個數等於該結點的度):
缺點:雖然這種方法克服了浪費空間的缺點,但是由於各個結點的連結串列是不相同點的結構,加上要維護結點的度的數值,在運算上就會帶來時間上的損耗。
2.1雙親孩子表示法(把每個結點的孩子排列起來,以單鏈表作儲存結構,則n個結點有n個孩子連結串列,如果是葉子結點則此單鏈表為空。然後n個頭指標又組成一個線性表,採用順序儲存結構,存放進一個以為陣列中。
child |
next |
data |
firstchild |
3.孩子兄弟表示法
任意一棵樹,它的結點的第一個孩子如果存在就是唯一,它的右兄弟如果存在也是唯一的。因此,我們設定兩個指標,分別指向該節點的第一個孩子和此節點的右兄弟。
data |
firstchild |
rightsib |
二叉樹(Birnary Tree):n(n>=0)個結點的有限集合,該集合或者為空集(稱為空二叉樹),或者由一個根節點和兩顆互不相交的,分別稱為根結點的左子樹和右子樹的二叉樹組成。
特殊的二叉樹:
1.斜樹
2.滿二叉樹
3.完全二叉樹
二叉樹的順序儲存結構:一般只用於完全二叉樹
二叉樹的鏈式儲存結構:二叉連結串列,二叉樹每個結點最多有兩個孩子,所以為它設定一個數據域和兩個指標域。
lchild |
data |
rchild |
二叉樹的遍歷:
1.前序遍歷
2.中序遍歷
3.後序遍歷
4.層序遍歷
線索二叉樹(看不懂):把指向前驅和後繼的指標稱為線索,加上線索的二叉樹表稱為線索連結串列,相應的二叉樹就稱為線索二叉樹(Threaded Binary Tree)。
二叉樹線索化:實質上就是將二叉連結串列中的空指標改為指向前驅或後繼的線索。線索化的過程就是在遍歷的過程中修改空指標的過程。
數,森林與二叉樹之間的轉換:
1.樹轉換為二叉樹
2.森林轉換為二叉樹
3.二叉樹轉換為樹
4.二叉樹轉換為森林
赫夫曼樹及其應用:壓縮,赫夫曼編碼。
帶權路徑的二叉樹。
第7章 圖
對於具有e條邊的無向圖,它的鄰接表中有2e個邊結點
第8章 查詢
查詢表:由同一型別的資料元素(或記錄)構成的集合。
關鍵字:資料元素中某個資料項的值,又稱為鍵值,用它可以標識一個數據元素。也可以標識一個記錄的某個資料項(欄位),稱為關鍵碼。
次關鍵字:可以標識多個數據元素(或記錄)的關鍵字。
查詢:根據給定的某個值,在查詢表中確定一個其關鍵字等於給定值得資料元素(或記錄)。
靜態查詢表(目的僅僅是為了查詢):只作查詢操作的查詢表。
1.查詢某個“特定”的資料元素是否在查詢表中。
2.檢索某個“特定的”資料元素和各種屬性。
動態查詢表:在查詢過程中同時插入查詢表不存在的資料元素,或者從查詢表中刪除已經存在的某個資料元素。
1.查詢時插入資料元素。
2.查詢時刪除資料元素。
8.3 順序表查詢:
一堆書散亂在地上,然後把它們放好後查詢。
1.順序查詢又叫線性查詢。
2.順序表查詢優化:從尾部查詢,避免查詢時下標越界。
8.4 有序表查詢
1.折半查詢
2.插值查詢(折半查詢的改進):根據查詢關鍵字key與查詢表中最大最小記錄的關鍵字比較後的查詢方法,其核心:(key-a[low])/(a[high]-a[low])。適用於表長較大,而關鍵字又分佈比較均勻的查詢表。不適用分佈極端不均勻的查詢表。
3.斐波那契查詢(看不懂):
斐波那契性質:前一個數除以後一個相鄰數字,數值趨向於黃金比例值。
8.5 線性索引查詢
資料結構的最終目的是提高資料的處理速度,索引是為了加快查詢速度而設計到的一種資料結構。
索引就是把一個關鍵字與它對應的記錄想關聯的過程,一個索引由若干個索引項構成,每個索引項至少包含關鍵字和其對應的記錄在儲存器中的位置等資訊。
索引是組織大型資料庫以及磁碟檔案的一種重要技術。
索引結構分為:線性索引,樹形索引和多級索引。
線性索引:線性索引就是將索引項集合組織為線性結構,也成為索引表。
1.稠密索引:將資料集中的每個記錄對應一個索引項,索引項一定是按照關鍵碼有序的排列。
2.分塊索引:把資料集的記錄分成若干塊,並且這些塊滿足:塊內無序,塊間有序。
3.倒排索引(看不懂):由屬性來確定記錄的位置。
8.6 二叉排序樹(鏈式儲存)
1.二叉排序樹,又稱為二叉查詢樹。它或者是一個空樹,或者是具有下列性質的二叉樹:
若它的左子樹不為空,則左子樹上所有結點的值均小於它的根結點的值。
若它的右子樹不為空,則右子樹上所有結點的值均大於它的根結點的值。
它的左,右子樹也分別為二叉排序樹。
二叉排序樹的插入操作
二叉排序樹的刪除操作
8.7 平衡二叉樹(AVL樹)
解決如何讓二叉排序樹平衡?
平衡二叉樹是一種二叉排序樹,其中每一個節點的左子樹和右子樹的高度差至多等於1。是一種高度平衡的二叉排序樹。
距離插入結點,且平衡因子的絕對值大於1的結點為根的子樹,我們成為最小不平衡子樹。
將二叉樹上結點的左子樹深度減去右子樹深度的值稱為平衡因子BF,所有結點平衡因子只能是-1,0,1。
8.8 多路查詢樹(B樹)
多路查詢樹,其每一個結點的孩子數可以多於兩個,且每一個結點處可以儲存多個元素。
4種特殊形式:
1.2-3樹
2.2-3-4樹
3.B樹
4.B+樹
8.9 散列表查詢(雜湊表)概述
雜湊技術是在記錄的儲存位置和它的關鍵字之間建立一個確定的對應關係f,使得每個關鍵字key對應的儲存位置f(key)。查詢時,根據這個確定的對應關係找到給定值key的對映f(key),若查詢集合中存在這個記錄,則必定在f(key)的位置上。
把f叫做雜湊函式或者雜湊函式。
採用雜湊技術將記錄儲存在一塊連續的儲存空間中,這塊連續的儲存空間稱為散列表或者雜湊表。
雜湊技術既是一種儲存方法,也是一種查詢方法。
雜湊技術的記錄不存在什麼邏輯關係,它只與關鍵字有關聯,雜湊主要是面向查詢的儲存結構。
8.10 雜湊函式的構造方法
1.直接定址法:取關鍵字的某個線性函式值為雜湊地址。f(key)=a x key+b (a,b為常數)。
2.數字分析法:適合處理關鍵字位數比較大的情況。
3.平方取中法:適合處理不知道關鍵字的分佈,而位數又不是很大的情況。
4.摺疊法:適合事先不知道關鍵字的分佈,適合關鍵字位數比較多的情況。
5.除留餘數法:
6.隨機數法:
8.11 處理雜湊衝突的方法
1.開放地址發:一旦發生衝突,就去尋找下一個空的散列表地址,只要散列表足夠大,空的雜湊地址總能找到,並將記錄存入。
2.再雜湊函式法
3.鏈地址發
4.公共溢位區法
雜湊表:雜湊表是一種根據關鍵碼去尋找值的資料對映結構,該結構通過把關鍵碼對映的位置去尋找存放值的地方。
最典型的的例子就是字典,大家估計小學的時候也用過不少新華字典吧,如果我想要獲取“按”字詳細資訊,我肯定會去根據拼音an去查詢 拼音索引(當然也可以是偏旁索引),我們首先去查an在字典的位置,查了一下得到“安”,結果如下。
這過程就是鍵碼對映,在公式裡面,就是通過key去查詢f(key)。其中,按就是關鍵字(key),f()就是字典索引,也就是雜湊函式,查到的頁碼4就是雜湊值。
第9章 排序
總結:先吐槽一下,CSDN部落格沒有設定行高的功能?不能Table?只能點上方工具欄首行縮排,還是縮3個的?拖到下方然後發現首行工具欄找不著然後再拖大進度條回去,首行工具欄不固定?頭大......over
資料結構就是如果放置一堆資料,然後怎麼查詢它,最大的思考就是怎麼最快的查詢到想要的資料!
物理結構就是在記憶體中實際放的位置,邏輯結構就是它們之間的關係。
每個資料結構都有順序儲存結構和鏈式儲存結構。