積累-數據結構與算法介紹

前言:
貌似程序員一直在說數據結構與算法,但是到底是什麼纔是數據結構與算法!?
以下是我自己整理的資料,對數據結構與算法有一個較爲清晰的認識,希望能幫到大家。

一、 數據結構的分類與算法
1. 數據結構可以分爲:
“數據的邏輯結構”:數據元素間的邏輯關係。
“數據的物理結構(存儲結構)” :數據元素在內存中的存放方式。
2. 算法:
算法實際就是在具體的存儲結構上,對數據元素進行的運算操作,如:檢索、排序、插入、刪除、修改等。

二、 圖解
1. 數據的邏輯結構
這裏寫圖片描述
2. 數據的存儲結構
順序存儲:數據元素放在一片連續的存儲單元中,邏輯上相鄰的單元存放到計算機內存仍然相鄰。
鏈接存儲:所有數據元素存放在不連續的存儲單元中,但元素之間的關係可以通過地址確定,邏輯上相鄰的元素存放到計算機內存後不一定是相鄰的。
索引存儲:存放數據元素的同時,還要建立附加的索引表(關鍵字,地址),其中關鍵字是唯一能標識一個接點的數據項。
散列存儲:通過構造散列函數,用函數的值來確定數據元素存放的地址。

  1. 數據的邏輯結構(現實中)採用哪種數據的存儲結構(內存中),來適應開發中不同的情況,這就是數據結構!

三、 各種邏輯結構常用的哪種的存儲結構,詳解
1. 線性表
線性表是具有相同類型的n個(n>=0)個數據元素組成的有限序列。
存儲方式
1.1 順序存儲
順序存儲以結點爲單位,按結點在表中的次序依次存儲,
結點在表中的邏輯次序和其在存儲器中的物理次序一致。
如(array數據,arrayList等)
1.2 鏈式存儲
每個表元素對應鏈表的一個結點,結點含有值域和鏈域。
值域用以存儲表元素,鏈域用於存儲結點後繼結點的存儲
地址,最後一個結點的鏈域爲空,無後繼結點。
如(linkedList)
1.3 順序表(採用順序存儲的表)的優缺點
優點:適合隨機存儲和提取,直接找到第n個元素
缺點:插入、刪除元素時,需移動大量數據,耗費大量時間。使用前需要一次性分配固定大小的內存空間,且容量難以擴充。
1.4 鏈表(採用鏈式存儲的表)
1.線性表的鏈式存儲表示,即用一組任意的存儲單元存儲線
性表的數據元素(這組存儲單元可以是連續的,也可以是不連續的)。
• 在存儲結構中,數據結點地址不連續,插入刪除時不移動結點。
• 鏈表使用指向結點(結構類型)的指針,在執行期間,調用動態存儲管理函v數,產生結點,回收結點。
• 訪問結點時,使用一個“滑動”的訪問指針P,從表頭結點出發可以逐個訪問表中所有節點

四、 棧(先進後出,後來居上)
• 棧(Stack)也是一種線性結構,它的邏輯結構和線性表相同。
• 棧是按照“先進後出”的規則來操作的。
• 棧是在表的一端進行插入和刪除操作,允許插入和刪除操作的一端稱爲棧頂(top),另一端稱爲棧底
• 當表中沒有元素時稱爲空棧。
• 棧的插入操作,稱爲入棧(push)。
• 棧的刪除操作,稱爲出棧(pop)。
• 棧按物理存儲結構分:順序棧和鏈式棧。
這裏寫圖片描述

  1. 利用順序存儲方式實現的棧稱爲順序棧。
  2. 利用鏈式存儲結構實現的棧稱爲鏈棧。它的結構與鏈表類似,用linkstack來表示

五、隊列(先進先出)
• 隊列(Queue)是隻允許在一端進行插入,而在另一端進行刪
除的運算受限的線性表。
• 允許刪除的一端稱爲隊頭(Front)。
• 允許插入的一端稱爲隊尾(Rear)。
• 當隊列中沒有元素時稱爲空隊列。
• 隊列亦稱作先進先出(First In First Out)的線性表,簡稱爲FIFO。
這裏寫圖片描述

• 順序存儲結構稱爲順序隊列
順序存儲結構是在內存中開闢一個連續的空間用來存儲數
據,因此對於內存的需求和苛刻,必須是連續的空間。
• 鏈式存儲結構簡稱爲鏈隊列
鏈式存儲結構是採取鏈表指針來指示數據的存儲位置,這
就可以是在內存中隨意的存儲,沒有必須連續儲存空間的
要求。

五、 非線性結構 樹和二叉樹
1. 樹:
• 樹形結構是一種典型的非線性結構。
• 相對於僅可以表示數據元素之間一對一關係的線性結構,樹形結構可以表示數據元素間一對多的關係。
基本概念和基本術語
• 樹是n(n>=0)個節點的有限集。
• n=0時爲空樹。
• 在非空樹中,有且僅有一個根節點。
• n=1時,只有一個根節點,n>1時,根節點無前驅節點,其餘節點只有一個前驅節點,其餘節點是互不相交的有限集,其中每一個有限集是符合本定義的樹,稱爲根的子樹

  1. 二叉樹:樹的度小於等於2的樹爲二叉樹。
    • 滿二叉樹:一棵二叉樹中,所有分支結點都有左孩子
    和右孩子結點,並且葉子節點集中在樹的最下面一層。

    這裏寫圖片描述

• 完全二叉樹
二叉樹中,最多隻有最下面2層的結點的度數可以小於2,並且最下面一層的葉子結點都依次排在該層最左邊的位置上。
這裏寫圖片描述

二叉樹的遍歷
• 二叉樹的遍歷是指按照某種順序訪問二叉樹中的每個結點,使每個結點被訪問一次且僅被訪問一次。
• 遍歷方法
1. 先序訪問。
(1) 訪問根結點;
(2) 先序遍歷左子樹;
(3) 先序遍歷右子樹。
2.中序訪問。
(1) 中序遍歷左子樹;
(2) 訪問根結點;
(3) 中序遍歷右子樹。
3.後續訪問。
(1) 後序遍歷左子樹;
(2) 後序遍歷右子樹;
(3) 訪問根結點。
這裏寫圖片描述
• 樹形結構是一類非常重要的非線性結構,它可以很好的描述客觀世界中廣泛存在的具有分支關係或層次特性的對象,因此在計算機領域裏有着廣泛應用,如操作系統中的文件管理、編譯程序中的語法結構和數據庫系統信息組織形式等。

六、算法之查找(Search)
• 查找(Search) :
確定一個已給的數據是否出現在某個數據元素集合中。
• 查找(Searching)的定義是:
給定一個值K,在含有n個結點的表中找出關鍵字等於給定值K的結點。若找到,則查找成功,返回該結點的信息或該結點在表中的位置;否則查找失敗,返回相關的指示信息。
• 查找的方法
1. 順序查找
2. 二分查找(折半查找)
3. 分塊查找
4. 二叉樹查找(BST、B-樹、B+樹、B*樹)
5. 哈希查找
• 按查找表的結構可將查找表分爲靜態查找表和動態查找表兩類。
• 靜態查找靜態查找表是僅僅進行查詢和檢索操作,不改變查找表中數據元素間的邏輯關係的查找。
靜態查找法主要有:順序查找,折半查找,分塊查找等。
• 動態查找動態查找表是除了進行查詢和檢索操作外,還對查找表進行插入、刪除操作的查找,動態地改變查找表中數據元素之間的邏輯關係。
動態查找法主要有:二叉樹查找,哈希查找。

  1. 順序查找優缺點
    • 優點:
    算法簡單,且對錶的結構無任何要求,順序查找方法既適用於線性表的順序存儲結構,也適用於線性表的鏈式存儲結構(使用單鏈表作存儲結構時,掃描必須從第一個結點開始)。
    • 缺點:
    查找效率低,因此,當n較大時不宜採用順序查找。

  2. 二分查找優缺點
    • 優點:二分查找的查找效率非常高
    • 缺點:二分查找只適用順序存儲結構。爲保持表的有序性,在順序結構裏插入和刪除都必須移動大量的結點。因此,二分查找特別適用於那種一經建立就很少改動、而又經常需要查找的線性表。對那些查找少而又經常需要改動的線性表,可採用鏈表作存儲結構,進行順序查找。鏈表上無法實現二分查找。
    • 二分查找過程可用二叉樹來描述,我們把當前查找區間的中間位置上的記錄作爲根,左子表和右子表中的記錄分別作爲根的左子樹和右子樹,由此得到的二叉樹,稱爲描述二分查找的判定樹或比較樹。

  3. 分塊查找

  4. 把表長爲n的關鍵字線性表分成b塊,前b-1塊記錄個數爲s=n/b,第b塊的記錄個數小於等於s。
  5. 保證在每一塊中,結點的存放不一定有序,但塊與塊之間必須是分塊有序的(假定按結點的關鍵字值遞增有序)。即指後一個塊中所有記錄的關鍵字值都應比前一個塊中所有記錄的關鍵字值大。
  6. 建立一個索引表。索引表的每個元素對應一個塊,其中包括該塊內最大關鍵字值和塊中第一個記錄位置的地址指針。

這裏寫圖片描述
優缺點:
1. 有索引作用,在表中插入或刪除一個記錄時,只要找到該記錄所屬的塊,就在該塊內進行插入和刪除運算。
2. 因塊內記錄的存放是任意的,所以插入或刪除比較容易,無須移動大量記錄。
• 分塊查找的缺點
分塊查找的主要代價是增加一個輔助數組的存儲空間(構建索引表)和將初始表分塊排序的運算(實現分塊有序)

二叉查找樹(BST)
• 爲什麼用二叉樹?
1. 當用線性表作爲表的組織形式時,可以有三種查找法。其中以二分查找效率最高。
2. 但由於二分查找要求表中結點按關鍵字有序,且不能用鏈表作存儲結構,因此,當表的插入或刪除操作頻繁時,爲維護表的有序性,勢必要移動表中很多結點。這種由移動結點引起的額外時間開銷,就會抵消二分查找的優點。
3. 二分查找只適用於靜態查找表。若要對動態查找表進行高效率的查找,可以使用二叉樹查找,是一種動態查找法。
4. BST能用鏈表作存儲結構,實際上就是將數據元素組織成二叉樹形式,以達到與二分法相同的查找效率,而又具有鏈表的插入、刪除操作的靈活性。
• 二叉查找樹(BST)的定義
二叉查找樹又稱做二叉排序樹或二叉搜索樹,其定義爲:二叉查找樹或者是空樹,或者是滿足下面性質的二叉樹。

這裏寫圖片描述
這裏寫圖片描述
小結
1. BST:二叉查找樹,每個結點只存儲一個關鍵字,等於則命中,小於走左結點,大於走右結點;
2. B-樹:多路搜索樹,每個結點存儲M/2到M個關鍵字,非葉子結點存儲指向關鍵字範圍的子結點;所有關鍵字在整顆樹中出現,且只出現一次,非葉子結點可以命中;
3. B+樹:在B-樹基礎上,爲葉子結點增加鏈表指針,所有關鍵字都在葉子結點中出現,非葉子結點作爲葉子結點的索引;B+樹總是到葉子結點才命中;
4. B*樹:在B+樹基礎上,爲非葉子結點也增加鏈表指針,將結點的最低利用率從1/2提高到2/3;

哈希查找
• 基本概念
1. 哈希表(Hash Table)又稱散列表,是除順序表存儲結構、鏈接表存儲結構和索引表存儲結構之外的又一種存儲線性表的存儲結構。
2.哈希表主要目的是用於解決數據的快速定位問題。哈希表是種數據結構,它可以提供快速的插入操作和查找操作。
3.哈希表在所有的線性數據結構中,數組的定位速度最快,因爲它可通過數組下標直接定位到相應的數組空間,就不需要一個個查找。
• 哈希表存儲的基本思路
設要存儲的對象個數爲n,設置一個長度爲m(m≥n)的連續內存單元;以線性表中每個對象的關鍵字ki(0≤i≤n-1)爲自變量,通過一個稱爲哈希函數的函數h(ki),把ki映射爲內存單元的地址(或稱下標)h(ki),並把該對象存儲在這個內存單元中。這樣,h(ki)稱爲哈希地址(又稱散列地址)。
把如此構造的線性表存儲結構稱爲哈希表。
• 哈希衝突
1. 構造哈希表但是存在這樣的問題,對於兩個關鍵字ki和kj(i≠j),有ki≠kj(i≠j),但h(ki)=h(kj)。我們把這種現象叫做哈希衝突。
2. 通常把這種具有不同關鍵字而具有相同哈希地址的對象稱做“同義詞”,由同義詞引起的衝突稱作同義詞衝突。
• 在哈希表存儲結構的存儲中,同義詞衝突是很難避免的;
• 除非關鍵字的變化區間小於等於哈希地址的變化區間,而這種情況當關鍵字取值不連續時是非常浪費存儲空間的。
• 通常的實際情況是關鍵字的取值區間遠大於哈希地址的變化區間。
小結
1. 哈希函數是一個映象,即:將關鍵字的集合映射到某個地址集合上,它的設置很靈活,只要這個地址集合的大小不超出允許範圍即可;
2. 由於哈希函數是一個壓縮映象,因此,在一般情況下,很容易產生“衝突”現象,即:
key1   key2,而 f(key1) = f(key2)。
3. 很難找到一個不產生衝突的哈希函數。一般情況下,只能選擇恰當的哈希函數,
使衝突儘可能少地產生。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章