這一篇要總結的是五天查詢的最後一篇,雜湊查詢,也稱為雜湊查詢(本文以雜湊稱呼)。提起雜湊,我的第一印象就是c#中的hashtable類,它是由一組key/value的鍵值對組成的集合,它就是應用了雜湊技術。
那麼,什麼是雜湊查詢呢?在弄清楚什麼是雜湊查詢之前,我們要弄清楚雜湊技術,雜湊技術是在記錄的儲存位置和記錄的關鍵字之間建立乙個確定的對應關係f,使得每個關鍵字key對應乙個儲存位置f(key)。查詢時,根據這個確定的對應關係找到給定值的對映f(key),若查詢集合中存在這個記錄,則必定在f(key)的位置上。雜湊技術既是一種儲存方法,也是一種查詢方法。
六種雜湊函式的構造方法:
1,直接定址法:
函式公式:f(key)=a*key+b (a,b為常數)
這種方法的優點是:簡單,均勻,不會產生衝突。但是需要事先知道關鍵字的分布情況,適合查詢表較小並且連續的情況。
2,數字分析法:
比如我們的11位手機號碼「136***x7887」,其中前三位是接入號,一般對應不同運營公司的子品牌,如130是聯通如意通,136是移動神州行,153是電信等。中間四們是hlr識別號,表示使用者歸屬地。最後四們才是真正的使用者號。
若我們現在要儲存某家公司員工登記表,如果用手機號碼作為關鍵字,那麼極有可能前7位都是相同的,所以我們選擇後面的四們作為雜湊位址就是不錯的選擇。
3,平方取中法:
故名思義,比如關鍵字是1234,那麼它的平方就是1522756,再抽取中間的3位就是227作為雜湊位址。
4,摺疊法:
摺疊法是將關鍵字從左到右分割成位數相等的幾個部分(最後一部分位數不夠可以短些),然後將這幾部分疊加求和,並按雜湊表表長,取後幾位作為雜湊位址。
比如我們的關鍵字是9876543210,雜湊表表長三位,我們將它分為四組,987|654|321|0 ,然後將它們疊加求和987+654+321+0=1962,再求後3位即得到雜湊位址為962,哈哈,是不是很有意思。
5,除留餘數法:
函式公式:f(key)=key mod p (p<=m)m為雜湊表表長。
這種方法是最常用的雜湊函式構造方法。
6,隨機數法:
函式公式:f(key)= random(key)。
這裡random是隨機函式,當關鍵字的長度不等是,採用這種方法比較合適。
兩種雜湊函式衝突解決方法:
我們設計得最好的雜湊函式也不可能完全避免衝突,當我們在使用雜湊函式後發現兩個關鍵字key1!=key2,但是卻有f(key1)=f(key2),即發生衝突。
方法一:開放定址法:
下面是實現**:
c#版本:
namespace程式輸出結果如圖:hashsearch.csharp
;
static
void main(string
args)
console.writeline(
"展示雜湊表中的資料:
",string.join(","
,hashtable));
while (true
)
", result);}}
//////
雜湊表插入
/// ///
雜湊表 ///
待插入值
public
static
void insert(int hashtable, int
data)
//將待插入值存入字典中
hashtable[hashaddress] =data;
}//////
雜湊表查詢
/// ///
雜湊表 ///
待查詢的值
///public
static
int search(int hashtable, int
data)
//查詢成功,返回值的下標
return
hashaddress;
}//////
雜湊函式(除留餘數法)
/// ///
待操作雜湊表
//////
返回資料的位置
public
static
int hash(int hashtable, int
data)}}
c語言版:
#include "程式輸出結果如圖:stdio.h
"#include
"stdlib.h
"#include
"io.h
"#include
"math.h
"#include
"time.h
"#define ok 1
#define error 0
#define true 1
#define false 0
#define success 1
#define unsuccess 0
#define hashsize 7 /* 定義雜湊表長為陣列的長度 */
#define nullkey -32768 typedef
intstatus;
typedef
struct
hashtable;
int m=0; /*
雜湊表表長,全域性變數
*//*
初始化*/
status init(hashtable *hashtable)
return
ok;}
/*雜湊函式(除留餘數法)
*/int hash(int
data)
/*插入
*/void insert(hashtable *hashtable,int
data)
//插入值
hashtable->elem[hashaddress]=data;}/*
查詢*/
int search(hashtable *hashtable,int
data)
//查詢成功
return
hashaddress;}/*
列印結果
*/void display(hashtable *hashtable)
printf(
"\n**********展示完畢**********\n");
}void
main()
; printf(
"***************雜湊查詢(c語言版)***************\n");
//初始化雜湊表
init(&hashtable);
//插入資料
for (i=0;i)
display(&hashtable);
//查詢資料
result= search(&hashtable,29
);
if (result==-1) printf("
對不起,沒有找到!");
else printf("
29在雜湊表中的位置是:%d
",result);
getchar();
}
資料結構和演算法系列10 五大查詢之二分查詢
二分查詢也屬於順序表查詢範圍,二分查詢也稱為折半查詢。二分查詢 有序 的時間複雜度為o logn 那麼什麼是二分查詢呢?二分查詢的基本思想是,在有序表中,取中間記錄作為比較物件,若給定值與中間記錄的關鍵字相等,則查詢成功 若給定值小於中間記錄的關鍵字,則在中間記錄的左半區繼續查詢 若給定值大於中間記...
資料結構和演算法系列10 五大查詢之二分查詢
二分查詢也屬於順序表查詢範圍,二分查詢也稱為折半查詢。二分查詢 有序 的時間複雜度為o logn 那麼什麼是二分查詢呢?二分查詢的基本思想是,在有序表中,取中間記錄作為比較物件,若給定值與中間記錄的關鍵字相等,則查詢成功 若給定值小於中間記錄的關鍵字,則在中間記錄的左半區繼續查詢 若給定值大於中間記...
資料結構與演算法系列13 二分查詢
二分查詢演算法是一種針對有序集合的查詢演算法,也叫折半查詢。每次都通過跟區間的中間元素對比,將待查詢的區間縮小為之前的一半,直到找到要查詢的元素,或者區間被縮小為0。特別注意前提是針對有序的資料集合 二分查詢是一種非常高效的查詢演算法,他的時間複雜度是o logn 我們可以假設資料大小是n,每次查詢...