Hash算法

哈希表查找:Hash

在查找数据时需要进行一系列的比较运算,无论是顺序查找、二分查找、索引查找、这类的查找算法都是建立在比较的基础上的,但最理想的查找算法是不经过任何比较,一次存取就能查找到数据,那么就需要在存储位置和它的关键字之间建立一个确定的对应关系,使每个关键字和数据中的唯一的存储位置相对应。在查找时,根据对应关系找到给定的关键字所对应的数据,这样可以不经过比较可以直接取得所查找的数据。

我们称存储位置在关键字之间的对应关系为哈希函数,按这个思想建立的表为哈希表。

设计哈希函数的方法:
直接定值法:

取关键字的值或某个线性函数作为k哈希地址:H(key) = key 或H(key)=a*key-b,但这种方法对数据有很高的要求。

问题:假设有10000个范围在0~255之间的随机整数,请任意输入0~255之间的一个整数,帮查询该整数总共出现了多少次?
#include <stdio.h>
#include <stdlib.h>
​
int main(int argc,const char* argv[])
{
    int arr[10000] = {};
​
    for(int i=0; i<10000; i++)
    {
        arr[i] = rand() % 256;
    }
​
    //  建立哈希表
    int hash[256] = {};
    //  通过直接定值法 建立哈希函数
    for(int i=0; i<10000; i++)
    {
        hash[arr[i]]++;
    }
​
    unsigned char num = 0;
    printf("请输入:");
    scanf("%hhu",&num);
​
    printf("次数:%d\n",hash[num]);
}  
​

时间复杂度:O(1)

但是有很大的局限性,因为很多数据是无法直接用做数组的下标的,其次可能会出现数据量少,但是数据值的差值较大,导致哈希表长度过大,造成内存浪费

数字分析法:

分析数据的特点设计哈希,常用方法是找到最大最小值,最大值-最小值+1 确定哈希表的长度,通过 数据-最小值 访问哈希表下标

以上两种方法局限比较大,但计算出的哈希地址没有冲突的可能,以下方法:平方取中法、折叠法、除留余数法等方法对关键字的要求不要,但计算出的哈希地址可能会有冲突。称为哈希冲突

解决哈希值冲突的方法:
  • 开方地址法

  • 再哈希法

  • 链地址法

  • 创建公共溢出区

哈希查找的优点:

查找速度极快,时间复杂度能达到O(1)。

哈希查找的缺点:

1、局限性比较大,对数据的要求比较高。

2、设计哈希函数麻烦,没具体的设计哈希函数的方法,只是有一些大致的思路。

3、需要建立哈希表,占用了额外的空间。

Hash函数的应用:MD5、SHA-1都属于Hash算法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中常用的 Hash 算法有以下几种: 1. MD5(Message Digest Algorithm 5):MD5 是一种单向加密算法,不可逆,常用于验证数据的完整性和一致性。 ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class HashAlgorithms { public static void main(String[] args) throws NoSuchAlgorithmException { String input = "hello world"; MessageDigest md = MessageDigest.getInstance("MD5"); byte[] mdBytes = md.digest(input.getBytes()); StringBuilder hexString = new StringBuilder(); for (byte b : mdBytes) { hexString.append(String.format("%02x", b)); } System.out.println(hexString.toString()); } } ``` 2. SHA(Secure Hash Algorithm):SHA 也是一种单向加密算法,主要用于数字签名和验证数据的完整性。 ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class HashAlgorithms { public static void main(String[] args) throws NoSuchAlgorithmException { String input = "hello world"; MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] mdBytes = md.digest(input.getBytes()); StringBuilder hexString = new StringBuilder(); for (byte b : mdBytes) { hexString.append(String.format("%02x", b)); } System.out.println(hexString.toString()); } } ``` 3. MurmurHash:MurmurHash 是一种高性能 Hash 算法,适用于大规模数据集的 Hash 计算。 ```java import com.google.common.hash.HashCode; import com.google.common.hash.HashFunction; import com.google.common.hash.Hashing; public class HashAlgorithms { public static void main(String[] args) { String input = "hello world"; HashFunction hf = Hashing.murmur3_128(); HashCode hc = hf.hashBytes(input.getBytes()); System.out.println(hc.toString()); } } ``` 4. CRC32(Cyclic Redundancy Check):CRC32 是一种循环冗余校验算法,常用于数据传输或存储时的错误检测。 ```java import java.util.zip.CRC32; public class HashAlgorithms { public static void main(String[] args) { String input = "hello world"; CRC32 crc32 = new CRC32(); crc32.update(input.getBytes()); System.out.println(crc32.getValue()); } } ``` 以上 Hash 算法都有其特定的应用场景,具体选择哪种算法需要根据具体的需求来决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值