資料結構整理筆記
書籍推薦
資料結構概述(教材選用嚴蔚敏、吳偉民,該書程式是偽演算法具體的程式是高一凡,西電的,大牛,只有程式。還有一本書,臺灣的黃國瑜自己寫的只有思路,程式是另外一個合作的清華的寫的,可惜很多錯的。)學完資料結構之後會對面向過程的函式有一個更深的瞭解,有本通俗易懂的資料結構的書《大話資料結構》用來入門很不錯。
資料結構的概述
定義
我們如何把現實中大量而反覆的問題以特定的資料型別(個體的資料型別)和特定的儲存結構(個體間的相互關係)儲存到主儲存器(記憶體)中,以及在此基礎上為實現某個功能(比如查詢某個元素,刪除某個元素,對所有元素進行排序)而執行的相應的操作,這個相應的操作也叫做演算法。
資料結構=個體+個體的關係
演算法=對儲存資料的操作
狹義:
資料結構是專門研究資料儲存的問題
資料的儲存包含兩方面:個體的儲存+個體關係的儲存
廣義:
資料結構既包含資料的儲存也包含資料的操作
對儲存資料的操作就是演算法
演算法
狹義:
演算法是和資料的儲存方式密切相關
廣義:
演算法和資料的儲存方式無關,這就是泛型思想
演算法的真正學法:
很多演算法你根本解決不了!!!!!!因為很多都屬於數學上的東西,所以我們把答案找出來,如果能看懂就行,但是大部分人又看不懂,分三步,按照流程,語句,試數。這個過程肯定會不斷地出錯,所以不斷出錯,不斷改錯,這樣反覆敲很多次,才能有個提高。實在看不懂就先背會。
衡量演算法的標準:
(1)時間複雜度
大概程式要執行的次數,而並非是執行的時間(因為同一程式在不同機器上執行的時間是不一樣的,有差異)
(2)空間複雜度
演算法執行過程中大概所佔用的最大記憶體
(3)難易程度(主要是應用方面看重)
(4)健壯性(不能別人給一個非法的輸入就掛掉)
資料結構的地位:
資料結構是軟體中最核心的課程
程式=資料的儲存+資料的操作+可以被計算機執行的語言
泛型
對於同一種邏輯結構,無論該邏輯結構的物理儲存是什麼樣子的,我們可以對它執行相同的操作。
泛型:(給你一種假象,只不過牛人從內部都弄好了)利用某種技術達到的效果就是:不同的儲存方式,執行的操作是一樣的
預備知識
指標
指標的重要性:(記憶體是可以被CPU直接訪問的,硬碟不行;cpu訪問記憶體
指標是C語言的靈魂
定義
地址:
地址就是記憶體單元的編號
從0開始的非負整數
範圍:0--FFFFFFFF[0-4G-1](地址線是32位,剛好控制2的32次)
指標:
指標就是地址地址就是指標
指標變數是存放記憶體單元地址的變數
指標的本質是一個操作受限的非負整數(不能加乘除,只能減)
分類:
1、基本型別的指標
2、指標和陣列的關係
結構體(C++中用類也能實現)
為什麼會出現結構體
為了表示一些複雜的資料,而普通的基本型別變數無法滿足要求
什麼叫結構體
結構體是使用者根據實際需要自己定義的複合資料型別
如何使用結構體
兩種方式:
struct Student st = {1000, "zhangsan", 20}
struct Student * pst = &st;
st.sid
pst->sid
pst所指向的結構體變數中的sid這個成員
注意事項:
結構體變數不間能加減乘除,但可以相互賦值
普通結構體變數和結構體指標變數作為函式引數的傳遞
(病毒就是靠訪問正在執行的那些程式所佔用的記憶體。Java中規定區域性變數必須初始化,因為這些變數一開始都是垃圾值,但是屬性不是必須初始化的,因為已經預設初始化為0)動態記憶體分配和釋放(動態分配的記憶體一定要手動釋放,否則造成記憶體洩露。)(java中A aa = new A();其實就是 A *p = (A *)malloc(sizeof(A)))
資料儲存結構
線性結構【把所有的結點用一根直線穿起來】
連續儲存【陣列】
1、什麼叫做陣列
元素型別相同,大小相等(陣列傳參,只要傳進去首地址和長度就行)
2、陣列的優缺點:
優點:
存取速度快
缺點:
事先必須知道陣列的長度
插入刪除元素很慢
空間通常是有限制的
需要大塊連續的記憶體塊
插入刪除元素的效率很低
離散儲存【連結串列】(我們搞底層的開發,類似於SUN公司的類)
定義:
n個節點離散分配
彼此通過指標相連
每個節點只有一個前驅節點,每個節點只有一個後續節點
首節點沒有前驅節點,尾節點沒有後續節點。
專業術語:
首節點:
第一個有效節點
尾節點:
最後一個有效節點
頭節點:
頭結點的資料型別和首節點的型別一樣
沒有存放有效資料,最最前面的,是在
首節點之前的,主要是為了方便對連結串列
的操作。
頭指標:(指向頭)
指向頭節點的指標變數
尾指標:
指向尾節點的指標
(頭結點有可能很大,佔的記憶體可能大,假設我想造一個函式輸出所有連結串列的值,那你如果不用頭指標型別做形參,那由於不同連結串列的頭節點不一樣大小,這樣就沒辦法找出形參)
確定一個連結串列需要幾個引數:(或者說如果期望一個函式對連結串列進行操作我們至少需要接收連結串列的那些資訊???)
只需要一個引數:頭指標,因為通過它我們可以推出連結串列的所有資訊。
(連結串列的程式最好一定要自己敲出來)
分類:
單鏈表
雙鏈表:
每一個節點有兩個指標域
迴圈連結串列
能通過任何一個節點找到其他所有的節點
非迴圈連結串列
(java中變成垃圾記憶體則會自動釋放,但是C和C++則不會,所以要手動釋放,否則會引起記憶體洩露。delete等於free)
演算法:
遍歷
查詢
清空
銷燬
求長度
排序
刪除節點
插入節點
連結串列的優缺點:
優點:
空間沒有限制
插入刪除元素很快
缺點:
存取速度很慢。
我們嚮往遠方,卻忽略了此刻的美麗