C 常用查詢演算法總結(二)

2021-08-21 21:14:13 字數 2362 閱讀 3405

查詢是在大量的資訊中尋找乙個特定的資訊元素,在計算機應用中,查詢是常用的基本運算,例如編譯程式中符號表的查詢,欄位的查詢,等等。

1、插值查詢

在介紹插值查詢之前,首先考慮乙個新問題,為什麼上述演算法一定要是折半,而不是折四分之一或者折更多呢?

同樣的,比如要在取值範圍1 ~ 10000 之間 100 個元素從小到大均勻分布的陣列中查詢5, 我們自然會考慮從陣列下標較小的開始查詢。

經過以上分析,折半查詢這種查詢方式,不是自適應的(也就是說是傻瓜式的)。二分查詢中查詢點計算如下:

mid=(low+high)/2, 即mid=low+1/2*(high-low);

通過模擬,我們可以將查詢的點改進為如下:

mid=low+(key-a[low])/(a[high]-a[low])*(high-low),

也就是將上述的比例引數1/2改進為自適應的,根據關鍵字在整個有序表中所處的位置,讓mid值的變化更靠近關鍵字key,這樣也就間接地減少了比較次數。

基本思想:基於二分查詢演算法,將查詢點的選擇改進為自適應選擇,可以提高查詢效率。當然,差值查詢也屬於有序查詢。

注:對於表長較大,而關鍵字分布又比較均勻的查詢表來說,插值查詢演算法的平均效能比折半查詢要好的多。反之,陣列中如果分布非常不均勻,那麼插值查詢未必是很合適的選擇。

複雜度分析:查詢成功或者失敗的時間複雜度均為o(log2(log2n))。

**實現:

//插值查詢

int insertionsearch(int a, int value, int low, int high)

else

} delete temp;

return -1;

}int main()

; int key=100;

int index=fibonaccisearch(a,sizeof(a)/sizeof(int),key);

cout<3、雜湊查詢

我們使用乙個下標範圍比較大的陣列來儲存元素。可以設計乙個函式(雜湊函式, 也叫做雜湊函式),使得每個元素的關鍵字都與乙個函式值(即陣列下標)相對應,於是用這個陣列單元來儲存這個元素;也可以簡單的理解為,按照關鍵字為每乙個元素"分類",然後將這個元素儲存在相應"類"所對應的地方。但是,不能夠保證每個元素的關鍵字與函式值是一一對應的,因此極有可能出現對於不同的元素,卻計算出了相同的函式值,這樣就產生了"衝突",換句話說,就是把不同的元素分在了相同的"類"之中。後面我們將看到一種解決"衝突"的簡便做法。

總的來說,"直接定址"與"解決衝突"是雜湊表的兩大特點。

什麼是雜湊函式?

雜湊函式的規則是:通過某種轉換關係,使關鍵字適度的分散到指定大小的的順序結構中,越分散,則以後查詢的時間複雜度越小,空間複雜度越高。

演算法思想:雜湊的思路很簡單,如果所有的鍵都是整數,那麼就可以使用乙個簡單的無序陣列來實現:將鍵作為索引,值即為其對應的值,這樣就可以快速訪問任意鍵的值。這是對於簡單的鍵的情況,我們將其擴充套件到可以處理更加複雜的型別的鍵。

演算法流程:

1)用給定的雜湊函式構造雜湊表;

2)根據選擇的衝突處理方法解決位址衝突;

常見的解決衝突的方法:拉鍊法和線性探測法。詳細的介紹可以參見:**演算法和資料結構: 十一 雜湊表。

3)在雜湊表的基礎上執行雜湊查詢。

雜湊表是乙個在時間和空間上做出權衡的經典例子。如果沒有記憶體限制,那麼可以直接將鍵作為陣列的索引。那麼所有的查詢時間複雜度為o(1);如果沒有時間限制,那麼我們可以使用無序陣列並進行順序查詢,這樣只需要很少的記憶體。雜湊表使用了適度的時間和空間來在這兩個極端之間找到了平衡。只需要調整雜湊函式演算法即可在時間和空間上做出取捨。

複雜度分析:

單純論查詢複雜度:對於無衝突的hash表而言,查詢複雜度為o(1)(注意,在查詢之前我們需要構建相應的hash表)。

使用hash,我們付出了什麼?

我們在實際程式設計中儲存乙個大規模的資料,最先想到的儲存結構可能就是map,也就是我們常說的kv pair,經常使用python的博友可能更有這種體會。使用map的好處就是,我們在後續處理資料處理時,可以根據資料的key快速的查詢到對應的value值。map的本質就是hash表,那我們在獲取了超高查詢效率的基礎上,我們付出了什麼?

hash是一種典型以空間換時間的演算法,比如原來乙個長度為100的陣列,對其查詢,只需要遍歷且匹配相應記錄即可,從空間複雜度上來看,假如陣列儲存的是byte型別資料,那麼該陣列占用100byte空間。現在我們採用hash演算法,我們前面說的hash必須有乙個規則,約束鍵與儲存位置的關係,那麼就需要乙個固定長度的hash表,此時,仍然是100byte的陣列,假設我們需要的100byte用來記錄鍵與位置的關係,那麼總的空間為200byte,而且用於記錄規則的表大小會根據規則,大小可能是不定的。

hash演算法和其他查詢演算法的效能對比:

C 常用查詢演算法

find 查詢元素 find if 按條件查詢元素 adjacent find 查詢相鄰重複元素 binary search 二分查詢演算法 count 統計元素個數 count if 按條件統計元素個數 1 find 查詢指定元素,返回找到的指定元素的迭代器,找不到則返回結束迭代器 函式原型 fi...

c 常用查詢演算法

演算法簡介 find 查詢元素 find if 按條件查詢元素 adjacent find 查詢相鄰重複元素 binary search 二分查詢法 count 統計元素個數 count if 按條件統計元素個數 find 功能描述 查詢指定元素,找到返回指定元素的迭代器,找不到返回結束迭代器end...

STL 常用演算法(二)查詢演算法

演算法簡介 1 find 功能描述 函式原型 include include include void test01 查詢容器中是否有 5 這個元素 vector int iterator it find v.begin v.end 5 if it v.end else class person 過...