哈希表查找(Java)

本文介绍了哈希表的基本思想,散列函数的构造标准和常见方法,如平均取中法、除余法和折叠法。并展示了哈希查找在Java中的实现,使用除余法构建哈希函数,链表法解决哈希冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

散列(哈希表)

1.基本思想:将关键字 (数据项)被映射到从0到Tablesize-1这个范围中的某个数,并且被放到适当的单元中。其中这个映射就叫做散列函数

0 H(Ki) Tablesize1

如图:




2.冲突:将两个不同的关键字映射到同一表的位置。如图:

用哈希函数将关键字映射到哈希表中(发生冲突的情况)

3.构造哈希函数的两个标准:(1)简单并且能快速计算;(2)能在地址中获取键的均部分。

4.构造哈希函数的几种常见方法:
 (1)平均取中法:具体做法是先通过关键字的平方值扩大相近数的差别,然后根据表长度取中间的几位数作为哈希值。
  例如:将一组关键字(0100,0110,1010,1001,0111)平方后得(0010000,0012100,1020100,1002001,0012321)若取表长为1000,则可取中间的三位数作为散列地址集:(100121,201,020,123)。

 (2)除余法:用关键字除以一个不大于哈希表长度m的正整数p(素数)所得的余数作为哈希地址的一种方法。

h(key) = key % p

 (3)折叠法:根据哈希表长将关键字尽可能分成若干段,然后将这几段的值相加,并将最高位的进位舍去,所得结果即为其哈希地址。
  例如:有一组关键字(4766934, 5656975, 4685673, 3547807,7569664),将这些数拆成2位,4位和1位数,然后再把它们相加,如下图:


折叠法位移构造哈希函数示意图

4.解决哈希冲突
 4.1开放定址法:当冲突发生时,按照某种方法探测表中的其他存储单元,直到找到空位置为止。

Hi = (H(key)+di) % m (i=1,2,...k(k m1)
  (1)线性探测法:di = 1,2,3,...,m1
  (2)二次探查法:di = 12,22,32,42,...,k2
  (3)双重哈希法 : 一旦发生冲突, 应用第二个哈希函数以获取备用位置。
 4.2链表法:将所有关键字为同义词的结点链接在同一个单链表中。

5.哈希查找的Java实现:
“`Java
/**
* 哈希查找的算法的实现
*
* {1,3,66,56,34,67,343,77,31,64,0,5,6,32,55,23,56}采用哈希表存放 用除余法构建哈希函数 用链表法解决哈希冲突
*
* @author zww
*
*/
public class HashTableSearch {
/* 哈希结点 */
private static class Node {
int key; // 链表中的键
Node next; // 下一个同义词
}

/* 在哈希表中查找关键字key */
public boolean HashSearch(int[] data, int key) {
    int p = 1;
    // 寻找小于或等于最接近表长的素数
    for (int i = data.length; i > 1; i--) {
        if (isPrimes(i)) {
            p = i;
            break;
        }
    }
    // 构建哈希表
    Node[] hashtable = createHashTable(data, p);
    // 查找key是否在哈希表中
    int k = key % p;
    Node cur = hashtable[k];
    while (cur != null && cur.key != key) {
        cur = cur.next;
    }
    if (cur == null) {
        return false;
    } else {
        return true;
    }

}

/*用求余,链表法构建哈希表*/
public Node[] createHashTable(int[] data, int p) {
    Node[] hashtable = new Node[p];
    int k;        //哈希函数计算的单元地址
    for (int i = 0; i < data.length; i++) {
        Node node = new Node();
        node.key = data[i];
        k = data[i] % p;
        if (hashtable[k] == null) {
            hashtable[k] = node;
        }else {
            Node current = hashtable[k];
            while(current.next != null) {
                 current = current.next;
            }
            current.next = node;
        }
    }
    return hashtable;
}

public boolean isPrimes(int n) {
    for(int i = 2; i <= Math.sqrt(n); i++ ) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

}

“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值