(一)分類
數據結構分爲5種。
1. 通用數據結構:數組,鏈表,樹,哈希表
2. 專用數據結構:棧,隊列,優先級隊列
3. 排序:插入排序,希爾排序,快速排序,歸併排序,堆排序
4. 圖:鄰接矩陣,鄰接表
5. 外部存儲:順序存儲,索引文件,B-樹,哈希方法
(二)通用數據結構
若想存儲真實世界中的類似人事記錄,存貨目錄,合同表或銷售業績等數據,則只需一般用途的數據結構。如:數組,鏈表,樹,和哈希表。它們被稱之爲通用的數據結構是因爲它們通過關鍵字的值來存儲並查找數據(而棧只允許存儲一定的數據項)
通用數據庫可以按照速度的快慢來分類:
數組和鏈表是最慢的,書相對較快,哈希表是最快的。
但使用最快的不一定是最好的,哈希表要求預先知道要存儲多少數據,數據對存儲空間的利用率也不是非常高。平衡樹編程起來很麻煩。
數組:
當存儲和操作數據庫時,在大多數情況下數組是首先應該考慮的結構。數組在下列情況下很有用:
1. 數據量比較小
2. 數據量的大小事先可預測
如果存儲空間足夠大的話,可以放鬆第二條,創建一個足夠大的數組來應付所有可
預見的數據輸入。
如果插入速度很重要的話,使用無序數組。如果查找速度很重要的話,使用有序數組,並用二分查找。數據元素的刪除總是很慢的,這事因爲要填充空出來的單元,
鏈表:
如果存儲的數據量不能預知或者需要頻繁地插入,刪除元素時,考慮使用鏈表。當有新的元素加入時,鏈表就開闢新的所需要的空間,所以它甚至可以佔滿全部可用的內存,在刪除過程中沒有必要像數組那樣添補“空洞”。
在一個無序的鏈表中插入一個元素時是相當快的,查找和刪除很慢,因此與數組一樣,鏈表最好也應用於數據量相對較小的情況。
二叉搜索樹
當確認數組和鏈表過慢時,二叉樹是最先應該考慮的結構。樹可以提供快速的O(logN)級的插入,查找和刪除。遍歷的時間複雜度是O(N)級的,這是任何數據結構遍歷的最大值。
對於遍歷一定範圍內的數據可以很快得出訪問數據的最大值和最小值。
對於程序來說,不平衡的二叉樹要比平衡二叉樹簡單得多,但不幸的是,有序數組能將他的性能降至O(N)級,不比一個鏈表好多少,然而如果可以保證數據時隨機進入的,就不需要用平衡二叉樹。
二叉搜索樹的特點:
1. 一個節點的左子節點的關鍵值小於這個節點,右子節點比這個節點大。
2. 查找key節點:查找從根節點開始,比較key與當前節點的大小(current),若key>current,current走向右邊,否則走左邊,直到找到key爲止。
3. 插入,:首先確定要插入的位置,這和2類似,插入的值稱爲葉子節點。
4. 刪除:被刪除的節點分三種情況,是葉子節點,有一個子節點,有兩個子節點。刪除葉子節點只需把該節點改爲null就可以了。刪除有一個子節點的節點:這個節點有兩個連接,連向父節點和連向它唯一的子節點。需要從這個序列中剪斷這個節點,把它的子節點直接連到他的父節點上。當刪除有兩個子節點的節點時,用它的中序後繼結點來代替它。找後繼節點就是找比初始節點關鍵值大的節點集合中最小的一個。即先找到右子節點,然後一直找左子節點直到最後。而這個後繼結點一定沒有左子節點。
平衡搜素樹:
在衆多的平衡樹中,紅--黑樹和2-3-4樹,他們都是平衡樹,並且無論插入數據是否有序,
他們都能保證性能爲O(logN).。然而對編程來說,這些平衡樹也很有挑戰性的,其中最難的是紅--黑樹。他們也應用了附加存儲而產生額外耗費,這對系統或多或少有些影響。
哈希表
哈希表的一個重要的概念是如何把關鍵字轉換成數組下標。在哈希表中是通過哈希函數來解決的。哈希化解決衝突有兩個方案:開放地址法和鏈地址法。
開放地址法:
線性檢測:就是線性查找空白單元。即從要插入的位置的數組下標一直遞增,直到找到空位。另外,哈希函數必須把關鍵字的範圍壓縮到數組的範圍。即:key%arraySize;
二次探測:距離:X+12,X+22,X+32,X42,X+52等等,但容易產生二次聚集
在哈希化:讓步長(constant)的範圍限制在1到constant,stepSize=constant-(key%constant)
哈希表在數據存儲結構中速度最快,這使他成爲計算機而不是人與數據交互時的必要,哈希表通常用於拼寫檢查器和作爲計算機語言編譯器的符號表,在這些應用中,程序必須在幾分之一的時間裏檢查上千的詞或符號。
當人而不是計算機初始化操作數據的存儲時,哈希表會很有用。正如前文所提到的,哈希表對數據的插入的順序並不敏感,因此可以取代平衡樹,但是哈希表的編程卻比平衡樹簡單多了。
哈希表需要有額外的存儲空間,尤其是對於開放定址法,因爲哈希表用數組作爲基本結構,所以,必須預先精確地知道待存儲的數據量。
用鏈表地址法處理衝突的哈希表是最健壯的實現方法。若能預先精確的知道數據量,在這種情況下用開放定址法編程最簡單,因爲不需要用到鏈表類。
哈希表並不提供任何形式的有序遍歷,或對最大最小值元素進行存取。如果這些功能重要的話,使用二叉搜索樹更好一些。
數據結構 |
查找 |
插入 |
刪除 |
遍歷 |
數組 |
O(N) |
O(1) |
O(N) |
—— |
有序數組 |
O(logN) |
O(N) |
O(N) |
O(N) |
鏈表 |
O(N) |
O(1) |
O(N) |
—— |
有序鏈表 |
O(N) |
O(N) |
O(N) |
O(N) |
二叉樹(一般情況) |
O(logN) |
O(logN) |
O(logN) |
O(N) |
二叉樹(最壞情況) |
O(N) |
O(N) |
O(N) |
O(N) |
平衡樹(一般和最壞情況) |
O(logN) |
O(logN) |
O(logN) |
O(N) |
哈希表 |
O(1) |
O(1) |
O(1) |
—— |