首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

用C和Java实现哈希表

哈希表是一种常见的数据结构,用于存储键值对。它通过将键映射到一个固定大小的数组索引来实现快速的插入、查找和删除操作。在C和Java中,我们可以使用不同的方法来实现哈希表。

在C中,我们可以使用数组和链表的组合来实现哈希表。具体步骤如下:

  1. 定义一个固定大小的数组,用于存储链表的头节点。
  2. 创建一个哈希函数,将键映射到数组索引。
  3. 当插入一个键值对时,通过哈希函数计算出数组索引,然后将键值对插入到对应链表的末尾。
  4. 当查找或删除一个键值对时,通过哈希函数计算出数组索引,然后在对应链表中遍历查找或删除。

以下是C语言实现哈希表的示例代码:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>

#define SIZE 10

// 定义哈希表节点
typedef struct Node {
    int key;
    int value;
    struct Node* next;
} Node;

// 创建哈希表
Node** createHashTable() {
    Node** hashTable = (Node**)malloc(sizeof(Node*) * SIZE);
    for (int i = 0; i < SIZE; i++) {
        hashTable[i] = NULL;
    }
    return hashTable;
}

// 哈希函数
int hashFunction(int key) {
    return key % SIZE;
}

// 插入键值对
void insert(Node** hashTable, int key, int value) {
    int index = hashFunction(key);
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->key = key;
    newNode->value = value;
    newNode->next = NULL;

    if (hashTable[index] == NULL) {
        hashTable[index] = newNode;
    } else {
        Node* curr = hashTable[index];
        while (curr->next != NULL) {
            curr = curr->next;
        }
        curr->next = newNode;
    }
}

// 查找键对应的值
int find(Node** hashTable, int key) {
    int index = hashFunction(key);
    Node* curr = hashTable[index];
    while (curr != NULL) {
        if (curr->key == key) {
            return curr->value;
        }
        curr = curr->next;
    }
    return -1;  // 未找到
}

// 删除键值对
void remove(Node** hashTable, int key) {
    int index = hashFunction(key);
    Node* curr = hashTable[index];
    Node* prev = NULL;
    while (curr != NULL) {
        if (curr->key == key) {
            if (prev == NULL) {
                hashTable[index] = curr->next;
            } else {
                prev->next = curr->next;
            }
            free(curr);
            return;
        }
        prev = curr;
        curr = curr->next;
    }
}

// 打印哈希表
void printHashTable(Node** hashTable) {
    for (int i = 0; i < SIZE; i++) {
        printf("Index %d: ", i);
        Node* curr = hashTable[i];
        while (curr != NULL) {
            printf("(%d, %d) ", curr->key, curr->value);
            curr = curr->next;
        }
        printf("\n");
    }
}

int main() {
    Node** hashTable = createHashTable();

    insert(hashTable, 1, 10);
    insert(hashTable, 2, 20);
    insert(hashTable, 11, 30);
    insert(hashTable, 21, 40);

    printf("哈希表:\n");
    printHashTable(hashTable);

    int value = find(hashTable, 11);
    printf("键11对应的值为:%d\n", value);

    remove(hashTable, 2);

    printf("删除键2后的哈希表:\n");
    printHashTable(hashTable);

    return 0;
}

在Java中,我们可以使用Java集合框架中的HashMap类来实现哈希表。HashMap类已经封装了哈希函数和相关操作,使用起来更加方便。以下是Java语言实现哈希表的示例代码:

代码语言:txt
复制
import java.util.HashMap;

public class HashTableExample {
    public static void main(String[] args) {
        HashMap<Integer, Integer> hashTable = new HashMap<>();

        hashTable.put(1, 10);
        hashTable.put(2, 20);
        hashTable.put(11, 30);
        hashTable.put(21, 40);

        System.out.println("哈希表:");
        System.out.println(hashTable);

        int value = hashTable.get(11);
        System.out.println("键11对应的值为:" + value);

        hashTable.remove(2);

        System.out.println("删除键2后的哈希表:");
        System.out.println(hashTable);
    }
}

以上就是用C和Java实现哈希表的方法和示例代码。哈希表在实际开发中广泛应用于数据存储和查找的场景,例如缓存、索引、字典等。腾讯云提供了多种云计算相关产品,如云数据库、云服务器、云存储等,可以根据具体需求选择适合的产品。更多关于腾讯云产品的信息,请参考腾讯云官方网站:https://cloud.tencent.com/

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++【哈希的模拟实现

,映射 至中对应的位置,实现存储,利用空间换时间,哈希的查找效率非常高,可以达到 O(1),哈希实现主要分为两种:闭散列 与 开散列,本文中将利用这两种方案实现哈希 ---- ️正文 1、模拟实现哈希...传统写法思路:创建一个容量足够的 新,将 原 中的数据映射至 新 中,映射完成后,交换 新 ,目的是为了更新当前哈希对象中的 关于 平衡因子 的控制 根据别人的试验结果,哈希中的存储的有效数据量超过哈希容器的...---- 3、源码 本文中涉及的所有代码位于下面这个 Gitee 仓库中 《哈希的模拟实现》 ---- 总结 以上就是本次关于 C++【哈希的模拟实现】的全部内容了,在本文中,我们主要对哈希的两种实现方式...:闭散列与开散列(哈希桶)进行了简单模拟实现,学习了 线性探测 单链表 这两种哈希冲突的解决方法,之前觉得没什么的单链表,在此处闪闪发光 ---- 相关文章推荐 C...++ 进阶知识 C++【初识哈希C++【一棵红黑树封装 set map】 C++【红黑树】 C++【AVL树】 C++【set map

21110

哈希函数哈希

其核心就是哈希函数哈希的应用! 哈希函数 哈希函数又称为散列函数,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。...哈希就是这么做的,一会再说!...哈希函数映射 哈希 哈希就是利用哈希函数,可以根据关键码而直接进行访问的数据结构,也就是将关键码(Key value)通过哈希函数映射到中的一个位置来进行访问。...因此对于JAVA中(C++标准中没有hashmap,只有第三方的),hashmap的实现也是类似,但是有一点改进,也就是如果发生冲突,将冲突对象添加到链表,假设冲突个数达到了8次,那么就会使用红黑树来代替链表...C++中的hash_map c++的hash_mapmap的用法很类似,但一定要区别,maphash_map虽然都是key-value形式,但是map的底层是红黑树,而hash_map的底层是hash

1.5K20

哈希函数哈希

我们将这16字节的输出域分为两半,高八位,低八位是相互独立的(这16位都相互独立)。...故此可以通过以下算式得到1000个哈希函数: f1+2f2=f3 f1+3f2=f4 f1+3*f2=f5 …… Hash 哈希的经典结构 在数据结构中,哈希最开始被描述成一个指针数组,...我们知道,哈希中存入的数据是key,value类型的,哈希能够put(key,value),同样也能get(key,value)或者remove(key,value)。...对于常见的几种数据结构来说,数组的特点是:容易寻址,但是插入删除困难。而链表的特点是:寻址困难,但是插入删除容易。...而对于哈希来说,它既容易寻址,同样插入删除容易,这一点我们从它的数据结构中是显而易见的。

70930

Java哈希以及哈希冲突

文章目录 Java哈希 概念 冲突 避免冲突 哈希函数的设计方法 常见哈希函数 负载因子调节 为什么负载因是0.75 解决哈希冲突两种常见的方法是:闭散列开散列 哈希 java 类集的关系 Java...设散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函数:Hash(key) = key% p(p<=m),将关键码转换成哈希地址 该方法进行搜索不必进行多次关键码的比较...已知哈希中已有的关键字个数是不可变的,那我们能调整的就只有哈希中的数组的大小。...的位运算比乘除的效率更高, 所以取3/4在保证hash冲突小的情况下兼顾了效率; 解决哈希冲突两种常见的方法是:闭散列开散列 解决哈希冲突两种常见的方法是:闭散列开散列 哈希 java 类集的关系...HashMap HashSet 即 java 中利用哈希实现的 Map Set java 中使用的是哈希桶方式解决冲突的 java 会在冲突链表长度大于一定阈值后,将链表转变为搜索树(红黑树

1K20

C++:哈希:闭散列哈希

哈希的概念 哈希就是通过哈希映射,让key值与存储位置建立关联。...可以把具有不同关键码而具有相同哈希地址的数据元素称为“同义词”。比如在上面的图中,可以看到24都为哈希冲突现象。...闭散列 为了解决哈希冲突,有闭散列开散列两种常见方法。接下来先介绍闭散列。...闭散列哈希的简单代码实现: 定义哈希存储的节点,使用状态来表示闭散列中元素的删除或空位置。 //定义状态。...负责因子的计算方法是哈希中有效数据个数/哈希的大小。 扩容的方法:创建一个新的哈希对象,然后遍历旧的哈希,根据旧的哈希的数据来重新计算数据的位置。

41520

哈希哈希冲突(手动实现哈希桶)

哈希桶(开散列法) 四、哈希桶的手动代码实现 五、哈希查找算法(基于线性探测法的实现) ---- 一、哈希是什么 哈希(Hash table)又称散列表,是一种存储结构,通常用来存储多个元素。...其它存储结构(线性、树等)相比,哈希查找目标元素的效率非常高。...,这个时候我们就可以将这个所谓的小集合搜索问题继续进行转化,例如: 每个桶的背后是另一个哈希 每个桶的背后是一棵搜索树 四、哈希桶的手动代码实现 /** * 哈希桶解决hash冲突(哈希桶的模拟实现...(基于线性探测法的实现哈希查找算法就是利用哈希查找目标元素的算法。...如下是使用哈希查找算法在 {5, 20, 30, 50, 55} 序列中查找 50 的 Java 程序: public class Demo { //哈希函数 public static int hash

68730

C++】哈希封装实现 unordered_map unordered_set

三、哈希封装实现 unordered_map unorderd_set 四、模拟实现完整代码 1、HashTable.h 2、unordered_map 3、unordered_set 4、test.cpp...(注:Java 中就不存在这个问题,Java 中的 map set 取名为 TreeMap TreeSet,unordered_map unordered_set 取名为 HashMap ...+ Reference (cplusplus.com) ---- 二、哈希的迭代器 红黑树一样,哈希也需要单独定义一个类来实现迭代器,不过由于哈希的迭代器是单向的,所以我们不用实现 operator...类;这是因为我们下面要使用哈希来封装实现 unordered_map unordered_set; 前面 红黑树封装实现 map set 一样,我们通过封装 哈希 的普通迭代器来实现 unordered_map...---- 三、哈希封装实现 unordered_map unorderd_set 哈希封装实现 unordered_map unorderd_set 其实与 红黑树封装实现 map set

1.1K30

哈希算法 数据结构_实现哈希构造查找算法

一、什么是哈希 1.概述 哈希(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。...通俗的理解一下: 如果我们有n个元素要存储,那我们就用l个内存单元来存储他们 然后我们有一个哈希函数f(x),我们把元素n函数计算得到哈希值,也就是f(n) f(n)就是存储元素n的那个内存单位的位置...,也就是元素在l中的下标 2.为什么哈希查询速度快 理解了哈希的基本思路,我们也就不难理解为什么哈希查询效率高了: 由于每个元素都能通过哈希函数直接计算获得地址,所以查找消耗时间非常少。...对此我们有两种方法,即开放地址法分离链表法: 开放地址法:如果某一哈希值对应的位置已经被占用了,就找另一个没被占用的位置。...二、代码实现 在这里我们实现一个基于分离链表法的哈希: 1.节点类 /** * @Author:huang * @Date:2020-06-20 10:19 * @Description:节点

57820

Java数据结构算法(十三)——哈希

Hash也称散列表,也有直接译作哈希,Hash是一种根据关键字值(key - value)而直接进行访问的数据结构。...我们可能想到每个单词会占用一个数组单元,那么数组的大小是5000,同时可以数组下标存取单词,这样设想很完美,但是数组下标单词怎么建立联系呢?   ...②、装填因子   已填入哈希的数据项长的比率叫做装填因子,比如有10000个单元的哈希填入了6667 个数据后,其装填因子为 2/3。...方法是把关键字用不同的哈希函数再做一遍哈希化,这个结果作为步长。对于指定的关键字,步长在整个探测中是不变的,不过不同的关键字使用不同的步长。   ...hashFunction(key); LinkNode node = hashArray[hashVal].find(key); return node; } }   链地址法中,装填因子(数据项数哈希容量的比值

1.1K80

C++:哈希unordered系列容器的封装

最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是 其底层结构不同(哈希...(2) 除留余数法(常用) 设散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函数:Hash(key) = key% p(p<=m),将关键码转换成哈希地址 哈希实现就是的这个方法...,其底层的是除留余数法, 解决其哈希冲突的方法有两种,即开放定址法拉链法。...2.4 开放定址法实现简单哈希 闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希未被装满,说明在哈希中必然还有空位置,那么可以把key存放到冲突位置中的“下一个” 空位置中去。...//自己实现的时候 一定要一步一步来, 先封装哈希 然后再封装简单的mapset 然后再封装迭代器让插入跑起来,然后再去考虑其他的一些细节问题, 不要一下子把所有的模板参数都加上 //要一步一步来

6710

PHP数组的哈希实现

2.在PHP中可以使用字符串或者数字作为数组的索引 , 数字索引直接就可以作为哈希的索引,数字也无需进行哈希处理 , 在PHP数组中如果索引字符串可以被转换成数字也会被转换成数字索引。...3.数组在插入元素的时候 , 会把字符串key计算出一个索引值 , 如果索引值中有数据 , 就在该索引位置存放一个链表 , 把新元素插到链表头上 但是, 元素bucket中存放着整个哈希的链表指针..., 整个哈希的链表顺序是按照插入的顺序进行链接的, 注意下图的红线 , 因此在foreach遍历时 , 会按照插入顺序进行输出 4.当哈希设置的数组个数满了时 , 再插入元素会进行数组扩容 , 有个二倍扩容的机制..., 并且需要把原先里面的元素从新哈希到新的数组里 . ?

1.2K20

Go 数据结构算法篇(十四):哈希哈希函数、哈希冲突哈希算法

实现原理是通过哈希函数(也叫散列函数)将元素的键名映射为数组下标(转化后的值叫做哈希值或散列值),然后在对应下标位置存储记录值。...哈希函数设计 要减少哈希冲突,提高哈希操作效率,设计一个优秀的哈希函数至关重要,我们平时经常使用的 MD5 加密就是一个哈希函数,但是其实还有其他很多自定义的设计实现,要根据不同场景,设计不同的哈希函数来减少哈希冲突...不管哪种探测方法,哈希中空闲位置不多的时候,哈希冲突的概率就会提高,为了保证操作效率,我们会尽可能保证哈希中有一定比例的空闲槽位,我们装载因子来表示空位的多少,装载因子=填入元素/哈希长度,装载因子越大...补充一张链地址法处理哈希冲突的图示: 链地址法解决哈希冲突图示 三、哈希算法 我们前面分享了哈希哈希函数哈希冲突,哈希算法简单理解就是实现前面提到的哈希函数的算法,用于将任意长度的二进制值串映射为固定长度的二进制值串...6、场景六:分布式缓存 分布式缓存其他机器或数据库的分布式不一样,因为每台机器存放的缓存数据不一致,每当缓存机器扩容时,需要对缓存存放机器进行重新索引(或者部分重新索引),这里应用到的也是哈希算法的思想

86130

C++】开散列哈希封装实现unordered_mapunordered_set

,他们不再以红黑树作为底层结构,而是以挂哈希桶的哈希作为底层结构,就是存储结点指针的vector来实现哈希哈希的每个位置是一个桶,桶结构是一个存储value的单链表,unordered_set...为了判断什么时候进行哈希的扩容,在hashTable类中多增加了一个无符号整型的_n变量,表示当前哈希中存储数据的个数,方便我们数据个数vector.size()作除法,看结果是否大于负载因子,...开散列的哈希是最常用的方式,库里面的unordered_mapunordered_set的也是哈希桶的方式实现的,我们模拟实现哈希桶也仿照库实现哈希结点node里面存储键值对下一个结点指针。...并且支持普通迭代器构造const迭代器的操作,实际上STL的所有容器在实现迭代器的时候,都会用下面的方式来支持普通迭代器构造const迭代器,如果是普通迭代器调用,那这里就是普通普通之间的拷贝,没啥因为编译器也支持这样的操作...如果我们此时这两个指针去构造const迭代器,而哈希迭代器类成员变量是两个普通指针,那在构造函数处就会发生const指针拷贝给普通指针的情况,此时权限会放大,所以如果你增加模板参数来实现const迭代器

1.6K30

c++实现哈希

准备工作 哈希的底层是一个vector的数组,数组中的每个节点都有一个pair类型的数据,其次还有一个指针指向当前链表节点的下一个节点,所以每个节点中有个一个pair类型的数据一个指向节点的指针,所以这里得创建一个类来描述每个节点...bucket类的准备工作,首先这个类有一个模板,模板中有三个参数,前两个表示存储数据的类型,最后一个表示的是仿函数,因为哈希的地城是vector数组,所以这里得添加一个vector容器用来存储数据一个整型变量用来记录容器中有效字符的个数即可...(0) { _tables.resize(10); } private: vector _tables; size_t _n; }; 看到这里我们的准备工作就完成了接下来就要实现哈希的每个函数...,如果这么做的话,在新的哈希桶里面又会不断地创建地节点,并且在函数结束地时候又会删除节点,如果节点的个数非常多的话这就会导致效率低下,所以我们这里就有一个改进思路就是能不能用已有的节点来插入到新创建的哈希呢...答案是可以的,我们依然是创建一个新的哈希然后改变其内部的大小,然后遍历之前的老哈希找到里面的元素并计算他在新上的位置,然后修改其节点内部指针的指向,那么这里的代码如下: if (_n / _tables.size

13230
领券