查詢演算法總體分為靜態查詢,和動態查詢,其中靜態查詢法,不改變查詢表結構,動態查詢表,可以進行插入和刪除操作。
一、查詢的基本概念
查詢,也可稱檢索,是在大量的資料元素中找到某個特定的資料元素而進行的工作。查詢是一種操作。
二、順序查詢
針對無序序列的一種最簡單的查詢方式。
時間複雜度為o(n)。
三、折半查詢
針對已排序序列的一種查詢方式。並且只適用於順序儲存結構的序列。要求序列中的元素基本不變,在需要做刪除和插入操作的時候,會影響檢索效率。
時間複雜度為o(logn)。查詢的最大次數為二叉樹的深度log(n)向下取整+1
五、雜湊(hash)表
關鍵字:雜湊函式、裝填因子、衝突、同義詞;
關鍵字和和儲存的位址建立乙個對應的關係:
add = hash(key);
解決衝突方法:
開放定址法 – 探測方式:線性探測、二次探測。
鏈位址法 – 利用鍊錶的方式。
查詢找效率不依賴於資料長度n,查詢效率非常快,很多能達到o(1),查詢的效率是a(裝填因子)的函式,而不是n的函式。因此不管n多大都可以找到乙個合適的裝填因子以便將平均查詢長度限定在乙個範圍內。
以上文字 **:
下面主要分析折半查詢和雜湊查詢
折半查詢主要用於有序的序列。當看到在有序的序列中查詢某個數時應該想到折半查詢。快速排序中的int partition(int *a,int start,int end)函式實現的功能是取乙個樞紐元素將陣列分成兩部分一部分比樞紐元素大,一部分比樞紐元素小。 將partition 函式結合折半查詢的思想可以解決很多問題。比如查詢陣列中第k個大的元素,取陣列中最小的k個數陣列中出現次數超過一半的數。
一定要注意二叉查詢只針對有序的陣列:二分查詢的基本思想:假設表中元素是按公升序排列,將表中間位置記錄的
關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置
記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功
#include#include#include#include#includeusing namespace std;
//非遞迴演算法
//在有序的陣列a[low...high]中查詢元素key預設為從小到大排序是否存在存在則返回元素所在索引不存在則返回-1
int binarysearch(int *a,int low,int high,int key)
int mid;
while(low<=high)
else if(a[mid]>key)
else if(a[mid]high)
int mid;
if(low<=high)
else if(a[mid]>key)
else if(a[mid]
雜湊查詢是指;根據雜湊函式得到資料元素的儲存位址的進行查詢的一種方法,其查詢的時間複雜度為o(1) 是典型的以空間換取時間的方法
雜湊函式是將資料元素對映為資料元素儲存位址的一種方法
雜湊查詢的操作步驟:
⑴用給定的雜湊函式構造
雜湊表;
⑵根據選擇的衝突處理方法解決位址衝突;
⑶在雜湊表的基礎上執行雜湊查詢。
雜湊查詢的核心是: 構造雜湊函式,和處理衝突:
假設資料元素為key 雜湊函式為 int hash(int key); 則資料元素key的儲存位址為address=hash(key) 對於用陣列來實現雜湊表來說 hash(key) 即為資料元素key
在陣列中的索引
構造雜湊函式的方法有:
1 直接定址法:hash(key)= key或 hash(key)=a*key+b 其中a和b是常數
直接定製法比較有用: 對於統計字元的個數可以用直接定製法構造雜湊函式,用陣列實現簡單的雜湊表。a['b'] ++;
2除留餘數法:這個方法比較常用也比較容易實現:
資料元素key的位址hash(key)=key%p其中p<=m; m為雜湊表的長度。根據經驗p 一般取小於m 的質數(最好接近m) 或包含小於20的質因數的合數
個人覺得掌握這兩種方法就夠了。其方法,要用到再看。
3 數字分析法
5 摺疊法:
處理衝突的方法有:
1開放定址法:hash(key) =(hash(key)+di)mod m 其中m為雜湊表的長度 當di=1,2,3,...m-1 時稱為線性探測法。而當di= 1^2,-1^2,2^2,-1^2...時稱為二次探測法。
自己寫程式時可以取di=1,2,3,......
2 鏈位址法:在查詢表中的每個記錄中增加乙個鏈域,鏈域中存放乙個具有相同雜湊函式值的記錄的儲存位址,利用鏈域就把若干個發生衝突的記錄鏈結在乙個鍊錶內,當鏈域的值為nul 時表示沒有後繼結點了
雜湊表的裝填因子: a=表中裝入的記錄數/雜湊表的長度
查詢找效率不依賴於資料長度n,查詢效率非常快,很多能達到o(1),查詢的效率是a(裝填因子)的函式,而不是n的函式。因此不管n多大都可以找到乙個合適的裝填因子以便將平均查詢長度限定在乙個範圍內。
a越小發生衝突的可能性越小。其實就是用空間換取時間嘛。空間犧牲越多衝突當然少了。。。
#include#include#include#include#includeusing namespace std;
#define hashtablesize 100 //定義雜湊表的長度
#define nullkey 0x7fffffff // 用於初始化雜湊錶用 0x7fffffff為32位整數所能取的最大值,一般元素不會取到這個值
typedef int hashtable[hashtablesize];//定義雜湊表的結構
//用除留餘數法 構造雜湊函式hash() 返回值為資料元素的儲存位址,對於陣列就是元素所在的索引
int hash(int key)
//初始化雜湊表
void inithashtable(hashtable hashtable)
{ for(int i=0;i
查詢演算法資料結構總結
查詢演算法分為靜態查詢和動態查詢兩種。靜態查詢是指沒有插入和刪除結點操作,只需查詢到按給定關鍵字的結點,而動態查詢是指存在查詢過程中插入和刪除結點的操作。對於靜態查詢,一般傾向於將資料組織成順序表的形式。無序查詢的複雜度為o n 有序的序列分兩種情況 當每個結點被查詢的概率相等時可以採用折半查詢的演...
演算法(資料結構)
空間不夠儲存 給40億個不重複的unsigned int的整數,沒排過序的,然後再給乙個數,如何快速判斷這個數是否在那40億個數當中 40億個數空間儲存的問題 利用對映 分析 unsigned 範圍是2 32 40億大約大約4g個數不到,常規方法肯定是不行的 我們你可以利用 伴隨陣列 那種思想利用記...
演算法 資料結構
演算法是程式的核心,演算法的好壞直接決定了程式的好壞 基礎的幾種演算法 二分查詢 氣泡排序 插入排序 選擇排序 快速排序 二分查詢 假設資料是按公升序排序的,對於給定值x,從序列的中間位置開始比較,如果當前位置值等於x,則查詢成功 若x小於當前位置值,則在數列的前半段中查詢 若x大於當前位置值則在數...