哈希表(散列表)查找

1.什么是哈希技术?

  哈希技术是在记录的存储位置记录的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。

  查找时,根据这个确定的对应关系找到给定值的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。

  哈希技术既是一种存储方法,也是一种查找方法。

2.什么是哈希表?

  采用哈希技术将记录存储在一块连续的存储空间中,这块连续的存储空间叫做哈希表(散列表)

  哈希表是基于数据来实现的,提供了快速的插入和删除操作。

3.哈希化
(1)直接将关键字作为索引
(2)将单词转换成索引
    ** 将字母转换成ASCII码,然后进行相加
    ** 幂的连乘
    ** 压缩可选值
 
  栗子1:
  已知一个线性表(38,25,74,63,52,48),假定采用散列函数h(key) = key%7 计算散列地址,并散列存储在散列表A【0....6】中,若采用线性探测方法解决冲突,则在该散列表上进行等概率成功查找的平均查找长度为
  答案:2.0
  平均查找长度=总的查找次数/元素数
  
  总的查找次数:
  38%7=3 (第1次出现3,无冲突,放在位置3,查找次数为1)
  25%7=4(第1次出现4,无冲突,放在位置4,查找次数为1)
  74%7=4(第2次出现4,有冲突,放在位置5,查找次数为2)
  63%7=0(第1次出现0,无冲突,放在位置0,查找次数为1)
  52%7=3(第2次出现3,有冲突,发现冲突3,4,5,故只能放到6,查找次数为4)
  48%7=6 (第1次出现6,有冲突,发现冲突6,0,故只能放到1,查找次数为3)
  1+1+2+1+4+3=12
  元素数=6
  所以:平均查找长度=12/6=2
 
  栗子2: 
  以下那种结构,平均来讲获取任意一个指定值最快?() 

  A.二叉排序树

  B.队列

  C.栈

  D.哈希表

解释:

  二叉排序树中,查找的平均时间复杂度是O(logn);

  对于栈和队列来说,查找就意味着把元素挨个出栈或者出队,故平均时间复杂度是O(n);

  而哈希表,直接通过关键码查找元素,平均为O(1);

  故哈希表速度是最快的

  因为哈希表,就是几乎是一一对应的你输入一个数,立马出结果,不用搜索的,其他的都得搜索 哈希表是O(1) , 二叉树是logN,栈是N,最慢。

讲完了,就这么简单,贴代码:
//Info
package com.hashtable;
//员工信息类
public class Info {
    private String key;
    private String name;
    public Info(String key,String name) {
        this.key=key;
        this.name=name;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

//HashTable
package com.hashtable;

public class HashTable {
    //哈希表底层是数组
    private Info[] arr;
    //默认的构造方法
    public HashTable () {
        //arr=new Info[10000];由于下面的取模可以把数组长度取小点
        arr=new Info[100];
    }
    //指定数组初始化大小
    public HashTable(int maxSize) {
        arr= new Info[maxSize];
    }
    //插入数据
    public void insert(Info info) {
        arr[hashCode(info.getKey())]=info;
    }
    //查找数据
    public Info find(String key) {
        return arr[hashCode(key)];
    }

    //哈希化
    //1.将字母转换成ASCII码,然后进行相加
    public int hashCode(String key) {
        //1.将字母转换成ASCII码,然后进行相加
        /*int hashVal=0;
        for (int i = key.length()-1; i>=0; i--) {
            int letter=key.charAt(i)-96;//A是97
            hashVal+=letter;
        }
        return hashVal;*/

        //幂的连乘
        int hashVal=0;
        int pow27=1;
        for (int i = key.length()-1; i >=0; i--) {
            int letter=key.charAt(i)-96;
            hashVal+=letter*pow27;
            pow27*=27;
        }
        return hashVal%arr.length;//可以取模,把数组长度改小点
    }
}

//TestHashTable
package com.hashtable;

public class TestHashTable {

    public static void main(String[] args) {
        HashTable ht=new HashTable();
        ht.insert(new Info("abc", "张三"));
        ht.insert(new Info("bbb", "李四"));

        System.out.println(ht.find("abc").getName());
        System.out.println(ht.find("bbb").getName());
    }

}

  

 

参考文档:

http://www.cnblogs.com/mcgrady/p/3294871.html

posted @ 2016-08-10 15:39  GumpYan  阅读(665)  评论(0编辑  收藏  举报