數據結構
數據結構是相互之間存在一種或多種特定關系的數據元素的集合。
- 數據:是描述客觀事物的符號,是計算機中可以操作的對象,是能被計算機識別,并輸入給計算機處理的符號集合。
- 數據元素:是組成數據的、有一定意義的基本單位,在計算機中通常作為整體處理。
- 數據項:數據項是數據不可分割的最小單位。
- 數據對象:是性質相同的數據元素的集合,是數據的子集。
邏輯結構
-
集合結構:幾何結構中的數據元素除了同屬于一個集合外,它們之間沒有其他關系。
集合結構 -
線性結構:線性結構中的數據元素之間是一對一的關系。
線性結構 -
樹形結構:樹形結構中的數據元素之間存在一種一對多的層次關系。
樹形結構 -
圖形結構:圖形結構的數據元素是多對多的關系。
圖形結構
在用示意圖表示數據的邏輯結構時,要注意兩點:
- 將每一個數據元素看做一個節點,用圓圈表示;
- 元素之間的邏輯關系用節點之間的連線表示,如果這個關系是有方向的,那么用帶箭頭的連線表示。
物理結構
物理結構是數據的邏輯結構在計算機中的存儲形式,是針對計算機的。數據的存儲結構用正確反映數據元素之間的邏輯關系,如何存儲數據元素之間的邏輯關系,是實現物理結構的重點和難點。
數據元素的存儲結構形式有兩種:
-
順序存儲結構:是把數據元素存放在地址連續的存儲單元里,其數據間的邏輯關系和物理關系是一致的。
順序存儲結構 -
鏈式存儲結構:是把數據元素存放在任意的存儲單元里,這組存儲單元可以使連續的,可以是不連續的。數據源歲的存儲關系并不能反應其邏輯關系,因此需要用一個指針存放數據元素的地址,這樣通過地址就可以找到相關聯數據元素的位置。
鏈式存儲結構
抽象數據類型
數據類型
是指一組性質相同的值的集合及定義在此集合上的一些操作的總稱。
C語言中,按照取值不同,數據類型可以分為兩類:
- 原子類型:不可再分解的基本類型,包括整形、實型、字符型。
- 結構類型:由若干個類型組合而成,是可以再分解的。
抽象數據類型
是指一個數學模型及定義在該模型上的一組操作。抽象的意義在于數據類型的數學抽象特性。(Point等)
算法
算法是解決特定問題求解步驟的描述,在計算機中表現為指令的有限序列,并且每條指令表示一個或多個操作。
數據結構與算法關系
算法定義
算法特性
算法有五個基本的特性:輸入、輸出、有窮性、確定性和可行性。
- 輸入輸出:算法具有零個或多個輸入,至少有一個或多個輸出。
- 有窮性:算法在執行有限的步驟之后,自動結束而不會出現無限循環,并且每一個步驟在可接受的時間內完成。
- 確定性:算法的每一步驟都具有確定的含義,不會出現二義性。
- 可行性:算法的每一步必須都是可行的,也就是說,每一步都能夠通過執行有限次數來完成。
算法設計的要求
- 正確性:算法的正確性是指算法至少應該具有輸入、輸出和加工處理無歧義性、能正確反映問題的需求、能夠得到問題的正確答案。但是算法的“正確”通常在用法上有很大的差別,大體分為一下四個層次:
- 算法程序沒有語法錯誤;
- 算法程序對于合法的輸入數據能夠產生滿足要求的輸出結果;
- 算法程序對于非法的輸入數據能夠得出滿足規格說明的結果;
- 算法程序對于精心選擇的,甚至是刁難的測試數據都有滿足要求的輸出結果。
實際上,這也是程序員程序的健壯性的一個體現。你無法保證輸入數據是完全按照給定的規則的,當輸入有一點不合規則就導致崩潰的程序是不健壯的。
2.可讀性:算法設計的另一目的是為了便于閱讀、理解和交流。
這個就不用多說了,程序員寫的程序,可讀性高意味著易于理解、調試與修改,可讀性差則經常會出現時間長了不知道自己寫了什么的窘況。
- 健壯性:當輸入的數據不合法時,算法也能做出相應的處理,而不是產生異常或莫名其妙的結果。
- 時間效率和存儲量要求:設計的算法應盡量滿足時間效率高和存儲量低的需求。用最少的空間花最少的時間解決同樣的問題。
算法效率的度量方法
- 事后統計:主要通過設計好的測試程序和數據,利用計算機計時器對不同算法編制的程序的運行時間進行比較,從而確定算法效率的高低。
- 事前分析估算:在計算機程序編制前,依據統計方法對算法進行估算。
函數的漸進增長
給定兩個函數f(n)和g(n),如果存在一個整數N,使得對于所有的n>N,f(n)總是比g(n)大,那么我們說f(n)的增長漸進快于g(n)。
結論:判斷一個算法好不好,只通過少量的數據是不能做出準確的判斷的,通過對比算法的時間函數的漸進增長性,可以得出某個算法,隨著n增大,它會越來越優于另一算法,或者越來越差與另一算法。這就是事前估算法的理論依據,通過算法時間復雜度來估算算法時間的效率。
算法的時間復雜度
- 大O階來表示算法的時間復雜度
- 推導大O階方法
-
常見的算法時間復雜度
常見的時間復雜度
最壞情況與平均情況
算法空間復雜度
線性表
零個或多個元素的有限序列。
抽象數據類型定義:
線性表的順序存儲結構
線性表的順序存儲結構指的是用一段地址連續的存儲單元依次存儲線性表的數據元素。
- 順序存儲方式:存儲空間的起始位置、線性表的最大容量、線性表的當前長度。
- 地址計算方法:首地址+單個存儲單元長度*下標
- 插入與刪除操作:具體步驟、時間復雜度
線性表的鏈式存儲結構
- 單鏈表
- 靜態鏈表
- 循環鏈表
- 雙向鏈表
棧與隊列
棧
棧是限定僅在表尾進行插入和刪除操作的線性表。允許插入和刪除的一段稱為棧頂,另一端稱為棧底,不含任何數據元素的棧稱為空棧。(FILO)
棧的抽象數據類型
棧的順序存儲結構——入棧、出棧
兩棧共享空間
棧的鏈式存儲結構
棧的應用——遞歸
棧的應用——四則運算表達式求值
隊列
隊列是只允許在一端進行插入操作,在另一端進行刪除操作的線性表。(FIFO)
隊列的抽象數據類型
![Upload 9CAB1B6D-D3BF-456F-A624-96BDB101D5B9.png failed. Please try again.]
循環隊列
隊列的鏈式存儲結構及其實現
串
串是由零個或多個字符組成的有限序列,又名字符串。
串的比較
串的抽象數據類型
串的存儲結構
- 順序
- 鏈式
樸素匹配算法——低效
KMP模式匹配算法
樹
樹是n個節點的有限集,在任意一顆非空樹中,有且僅有一個根節點,當n>1時,其余節點可分為m(m>0)個互不相交的有限集T1,T2...,其中每一個集合本身又是一棵樹,并稱為根的子樹。需要注意的還有兩點:
- n>0時根節點是唯一的,不可能存在多個根節點;
- m>0時,子樹的個數沒有限制,但他們一定是互不相交的。
節點分類
樹的節點包含一個數據元素及若干指向其子樹的分支,節點擁有的子樹數稱為節點的毒。度為0的節點稱為葉節點或終端節點;度不為0的節點稱為非終端節點或分支節點。除根節點之外,分支節點也稱為內部節點,樹的度是樹內各節點的度的最大值。
節點之間的關系
父子、兄弟、祖先。
其他相關概念
- 節點的層次、樹的深度、高度。
- 有序樹、無序樹。
- 森林是m(m>0)棵互不相交的樹的集合。
樹的抽象數據類型
樹的存儲結構
- 雙親表示法
- 孩子表示法
- 孩子兄弟表示法
二叉樹的定義
二叉樹是n(n>0)個結點的有限集合,該集合或者為空集,或者由一個根節點和兩棵互不相交的、分別稱為根節點的左子樹和又子樹的二叉樹組成。二叉樹特點如下:
- 每個結點最多有兩棵子樹,所以二叉樹中不存在度大于2的結點;
- 左子樹和右子樹是有順序的,次序不能顛倒;
- 即使一個結點只有一棵子樹,也要區分是左右子樹。
特殊二叉樹
- 斜樹
- 滿二叉樹
- 完全二叉樹
二叉樹的性質
- 在第i層上最多有2^(i-1)個結點
- 深度為k的二叉樹至多有2^k-1個結點
- 任意一顆二叉樹T,如果終端結點數為n0,度為2的結點樹為n2,則n0=n2+1
- 具有n個結點的完全二叉樹的深度為[log2(n) 向下取整]+1
- 如果對一棵有n個結點的完全二叉樹的結點按層序編號,則有
- 如果i=1,則結點i是二叉樹的根,若i>1,則父節點是[i/2 向下取整]
- 如果2i>n,則結點i無左孩子,否則其左孩子是結點2i
- 如果2i+1>n,則結點i無右孩子,否則其右孩子是結點2i+1
二叉樹的存儲結構
- 順序(一般只用于完全二叉樹,否則浪費存儲空間)
- 二叉鏈表
遍歷二叉樹
- 前序遍歷
- 中序遍歷
- 后序遍歷
- 層序遍歷
二叉樹的建立
樹、森林與二叉樹的轉換
二叉搜索樹
查找、插入、刪除節點算法
平衡二叉樹
插入、刪除節點算法
堆
最大堆、最小堆
哈弗曼樹、哈夫曼編碼