哈希表(Hashtable)

依然從咱們學習自問三部曲開始,什麼是哈希表?哈希表有什麼用?哈希表怎麼用?java

從百科上咱們能夠得知散列表(Hashtable)也被稱爲哈希表,它是根據關鍵碼值<Key value>而進行直接訪問的數據結構。它經過把關鍵碼值映射到表中的一個位置來訪問記錄,以加快查找熟讀。這個映射函數被稱爲哈希函數,存儲記錄的數組被稱爲散列表算法

那麼既然說能加快查找速度,那麼久不得不拿數組與鏈表進行比較了,數組你要查找一個元素得知道數組的下標,而鏈表卻須要從頭開始遍歷,直到找到咱們所須要的元素爲止,這耗費大量的時間。數組

哈希表是怎麼提升查找速度的數據結構

咱們但願輸入一個數的值就能夠找到該數所在的位置函數

 

 

哈希函數構造方法學習

1、關鍵詞爲數字優化

一、直接地址法spa

公式:index = a*key+bcode

package test;

public class collectiontdemo {
	public static int func(int i){
		return (i-3000)/2;
	}
	public static void main(String []args){
		int index;
		int []arr = new int[1000];
		//3000至3450之間的偶數
		for(int i=3000;i<3450;i+=2){
			index = func(i);
			arr[index] = i;
		}
		index = func(3200);
		System.out.println(index);
		System.out.println(arr[index]);
	}

		
}

  

 

 

 二、除留餘數法blog

公式:index =  key%p

p爲表的大小

package test;
//將數組arr2中的九個元素進行取模,而後隨機存到數組arr中
public class collectiontdemo {
    public static int func2(int key,int p){
        return key%p;
    }
    public static void main(String []args){
        int index;
        int p = 9;
        int []arr = new int[30];
        int arr2[] = {999,111,0,256,333,777,9,2546,1024};
        
        for(int i=0;i<arr2.length;i++){
            index = func2(arr2[i],p);
            arr[index] = i;
            
        }
        for(int i=0;i<arr2.length;i++){
            System.out.println(arr[i]);
        }

    }        
}

三、數字分析法

好比一個數組存了不少的電話號碼,這些號碼長度都爲11,咱們直接取值不太方便,若是咱們可以以號碼後四位做爲判斷標準,那麼查找起來也比較方便

package test;

public class collectiontdemo {
	public static int func3(char []value){
		char a =value[1];
		char b = value[3];
		char c = value[4];
		char d = value[2];
		return (int)a*100+(int)b*10+(int)c;
	}
	public static void main(String []args){
		String [] arr = new String [30];
		int p =29;
		int index;
		String arr2[]={"15764914325","13846478246","13756445236","18734628132",
				"13276482132"};
		for(int i=0;i<arr2.length;i++){
			char []arr1 = arr2[i].toCharArray();
			index = func3(arr1)%p;
			arr[index] =arr2[i];
		}
		for(int i=0;i<arr.length;i++){
			System.out.println(arr[i]);
		}

	}		
}

  

輸出結果

 

2、關鍵字爲字符串

一、ASCLL碼加和法

把每一個字符的ASCLL碼進行相加,進而獲得key值

這種方法很大機率會致使哈希衝突

二、前三個字符移位法

index =(key[0])*27+key[1]*27+key[2])mod TableSize

仍會形成衝突且會形成空間浪費

三、移位法

把全部的字母都進行移位,而後獲得key(32進制)

3、哈希衝突解決辦法

不一樣的樹在經過哈希函數運算後獲得的index相等,就把它們放入了相同的地址,致使數據被覆蓋。哈希衝突沒法避免,當數據很大而儲存空間較小的時候,不管多麼完美的哈希函數與方法都會存在哈希衝突,咱們能夠經過優化哈希函數來下降衝突的機率。

一、開放地址法

當衝突發生時,用某種探測算法在散列表中尋找下一個散列表空的地址,只要列表足夠大,總會找到。按照探測序列的方法,通常將開放地址法區分爲線性探查法、二次探查法、雙重散列法等。

咱們用除留餘數法將2六、3五、36記錄插入表中,取模爲8,而後再將18記錄插入表中,發現取模後地址不爲空,接下來就介紹這三種方法。

 

 

(1)線性探測法

index = a*index +i (i爲遞增的整數)

當2位置被佔領咱們就探查3位置,直到探查到5位置爲空爲止,當數據插入。容易出現越界,即探測完最後一個的時候所有滿了,而沒探測到前面卻爲空。

(2)二次探測法

index = a*index +i(i爲1^2   ,   -1^2    , 2^2,   -2^2   ,   3^2   ,   -3^2……q^2,  -q^2)

缺點是沒法探測整個散列空間。

(3)連地址法

將全部的哈希地址相同的記錄,都鏈接到鏈表當中。當有新的元素進來形成哈希衝突時,在衝突的地址鏈表後面加。

相關文章
相關標籤/搜索