哈希表(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)连地址法

将全部的哈希地址相同的记录,都链接到链表当中。当有新的元素进来形成哈希冲突时,在冲突的地址链表后面加。

相关文章
相关标签/搜索