因本人最近在惡補數據結構,學識經驗有限,如有不正之處望讀者指正,不勝感激;也望藉此平臺留下學習筆記以溫故而知新。這一篇博客主要是最近剛開始接觸大話數據結構一書,寫的通俗易懂,很多圖表幫忙理解,所以講隨手筆記分享至此,希望對您有所幫助。
查找
查找表:由同一類型的數據元素構成的集合
關鍵字:數據元素中某個數據項的值,又稱鍵值
查找:就是根據給定的某個值,在查找表中確定一個其關鍵字等於給定值的數據元素
查找表按照操作方式分兩類:靜態查找表和動態查找表
靜態查找表:只用作查找操作的查找表,主要操作有:
動態查找表:在查找的過程中同時插入查找表中不存在的數據元素,或者從查找表中刪除已經存在的某個數據元素,主要操作有:
順序表查找
順序查找又叫線性查找,過程是:從表中第一個(或者最後一個)記錄開始,逐個進行記錄的關鍵字和給定值的比較,若某個記錄的關鍵字和給定值相等,則查找成功,找到所查的記錄;如果直到最後一個相比較都不等,則表中沒有所查的記錄,查找不成功
順序查找的算法實現:
順序表查找優化
有序表查找
二分查找的前提是線性表中的記錄必須是關鍵碼有序,線性表爲順序存儲。
二分查找的思想:在有序表中,取中間值作爲比較對象,若給定值和中間記錄關鍵字相等,則查找成功,否則按照大小劃分繼續進行比價,直到結束爲止。
插值法對於二分查找的改進:代碼第八句
斐波拉契查找
斐波拉契數列
斐波拉契代碼
線性索引查找
線性索引三種方式:稠密索引、分塊索引、排序索引
稠密索引
在線性索引中,將數據集中的每個記錄對應一個索引項
特點:索引項有序,可以通過二分、插值等有序算法查找;但是對於數據集非常大的情況,對於內存有限的計算機,需要反覆訪問磁盤,查找性能大大降低了
分塊索引
把數據集的記錄分成了若干塊,並且這些塊塊內無序、塊間有序。
倒排索引
示例:
單詞索引表-->倒排索引
二叉排序樹
又叫二叉查找樹,或者是一顆空樹,或者具有以下性質:
- 若其左子樹不空,則左子樹上所有結點的值均小於其根結點的值
- 若其右子樹不空,則右子樹上所有結點的值均大於其根結點的值
- 其左右子樹也分別爲二叉排序樹
二叉樹結構定義
二叉排序樹查找的代碼實現
二叉排序樹插入:
二叉排序樹刪除操作
其中delete代碼
平衡二叉樹(AVL樹)
是一種二叉排序樹,其中每一個結點的左子樹和右子樹的高度差至多等於1.
平衡因子:二叉樹上結點的左子樹深度減去右子樹深度的值
平衡二叉樹實現
樹的結點構造
右旋操作:
左旋操作
左平衡旋轉處理的函數代碼
插入平衡二叉樹:
主函數調用調試:
說明:對於不平衡的二叉排序樹,查找效率是非常低的,此時構建這顆二叉樹爲平衡二叉樹,則查找時間複雜度爲O(logn),插入和刪除也是O(logn)
多路查找樹(B樹)
每一個結點的孩子數可以多於兩個,且每個結點處可以存儲多個元素;是查找樹,所有元素之間存在某種特定的排序關係
因爲每個結點可以存儲多個元素,以及孩子數的多少非常關鍵,所以按照特徵形式介紹如下四種:2-3樹,2-3-4樹,B樹,B+樹
2-3樹
其中每個結點都具有兩個孩子(2結點)或者三個孩子(3結點)。一個2結點包含一個元素和兩個孩子(或者沒有孩子,不能只有一個孩子),與二叉排序樹類似;一個3結點包含一小一大兩個元素和三個孩子(或者沒有孩子)。
2-3樹的插入
針對插入時要往3結點中插入一個新元素可能遇到的情況
1、
2、
3、
2-3樹的刪除
針對刪除一個元素可能遇到的情況
1、
2、
3、
2-3-4樹
2-3樹概念的推廣,一個4結點包含小中大三個元素和四個孩子,一個4結點要麼沒有孩子,要麼具有4個孩子
插入示例
刪除示例
B樹
B樹是一種平衡的多路查找樹,2-3樹和2-3-4樹都是其特例。結點最大的孩子數目稱爲B樹的階,2-3樹爲3階B樹,2-3-4樹是4階B樹
一個m階的B樹具有以下屬性
B樹進行查找時,是一個順時針查找結點和在結點中查找關鍵字的交叉過程
B+樹
一顆m階B+數和m階B樹的差異在於:
哈希表概述
目的:查找某個位置數據,其實就是--->存儲位置=function(關鍵字)
散列技術:在記錄的存儲位置和其關鍵字之間建立一個確定的對應關係,使得每個關鍵字對應一個存儲位置,查找時,根據這個確定的對應關係找到給定值的關鍵字的映射。這個映射關係稱爲散列函數,也叫哈希函數。
散列表查找步驟
Step1:在存儲時,通過散列函數計算記錄的散列地址,並按散列地址存儲該記錄。
Step2:查找記錄時,通過同樣的散列函數計算記錄的散列地址,按此散列地址訪問記錄
散列技術既是一種存儲方法,也是一種查找方法。與前述各種數據結構不同的是:
前面數據結構數據元素之間都有某種邏輯關係,可以可視化;
而散列技術只與關鍵字有關,數據間沒有邏輯關係,因此散列主要面向查找的存儲結構
散列最適合的求解場景是查找與給定值相等的記錄。
不適合的求解場景:一個關鍵字對應多條記錄的情況;範圍查找。
散列函數的構造方法
兩個原則:
1、計算簡單
2、散列地址分佈均勻
具體的構造方法介紹
直接定址法:直接取關鍵字的某個線性函數值爲散列地址
說明:適合查找表較小且連續的情況
數字分析法:
說明:適合處理關鍵字位數比較大的情況,如果事先知道關鍵字的分佈且分佈均勻
平方取中法
示例:1234,平方1234*1234 = 1522756, 抽取中間3位:227
說明:適合不知道關鍵字的分佈,而位數又不是很大的情況
摺疊法
將關鍵字從左到右分割成位數相等的幾部分,然後將這幾部分疊加求和,並按散列表表長,取後幾位作爲散列地址。
示例:
說明:適合關鍵字位數較多的情況
除留餘數法
示例
說明:餘數的選擇很重要,若散列表表長爲m,通常p爲小於或等於表長的最小質數或不包含小於20質因子的合數
隨機數法
F(Key) = random(key)
說明:當關鍵字長度不等時,採用這個方法構造散列函數是比較合適的
散列表查找實現
定義數據結構
進行初始化
定義散列函數
對散列表進行插入操作
有了散列表,需要的時候就可以直接通過散列表進行查找記錄了
散列表查找性能分析
1、散列函數是否均勻
2、處理衝突方法不同會導致平均查找長度不同
3、散列表的填裝因子,越小,產生衝突的可能性就越小