关闭

哈希表(散列)HashTable实现

标签: 哈希表
634人阅读 评论(0) 收藏 举报
分类:

  最近刷Leetcode发现凡是找字符串中重复字符或者数组中找重复数据的时候就不知道从何下手了。
  所以决定学习一下哈希表解题,哈希表的原理主要是解决分类问题,hash表是介于链表和二叉树之间的一种中间结构。链表使用十分方便,但是数据查找十分麻烦;二叉树中的数据严格有序,但是这是以多一个指针作为代价的结果。hash表既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。
  定义hash数据结构,我采用的解决冲突的方法是分离链接法。
  这里写图片描述

//单链表结构
typedef struct listnode* position;
typedef struct listnode* list;
struct listnode{
    ElementType data;
    position next;
};
//hash表结构
typedef struct hashtbl*  hashtable;
struct hashtbl {
    int tablesize;
    list *thelists;
};

哈希散列函数index = key%tablesize

index HashFunc(const ElementType key,int tablesize)
{
    //unsigned int hashval = 0;
    //while(*key != '\0')   
        //hashval = (hashval << 5) + *key++;
    //return hashval % tablesize;
    return key % tablesize;
}

创建hash表,并初始化

hashtable InitializeHashTable(int tablesize)
{
    hashtable H;
    H = (hashtable)malloc(sizeof(hashtable));
    if(NULL == H) return NULL;

    H->tablesize = tablesize;

    H->thelists = (list*)malloc(sizeof(list) * H->tablesize);
    int i = 0;
    for(i=0;i<H->tablesize;i++)//链表是有表头的单链表
    {
        H->thelists[i] = (list)malloc(sizeof(struct listnode));
        H->thelists[i]->next = NULL;
    }
    return H;
}

删除hash表

void DeleteHashTable(hashtable H)
{
    position P,tem;
    int i = 0;
    for(i=0;i<H->tablesize;i++)
    {
        P = H->thelists[i]->next;
        while(P != NULL)
        {
            tem = P;
            free(tem);
            P=P->next;
        }
    }
    free(H->thelists);
    free(H);
}

往hash表中插入新元素

position Find(ElementType key,hashtable H)
{
    position P;
    list L;
    L = H->thelists[ HashFunc( key, H->tablesize) ];
    P = L->next;
    while(P != NULL && P->data != key)
        P = P->next;

    return P;
}

void Insert(ElementType key,hashtable H)
{
    position pos,newnode;
    list L;
    pos = Find(key,H);
    if(pos == NULL)
    {
        newnode = (position)malloc(sizeof(position));
        L = H->thelists[ HashFunc( key, H->tablesize) ];
        newnode->data = key;
        newnode->next = L->next;
        L->next = newnode;
    }
}

打印hash表中所有的元素

void PrintHashTable(hashtable H)
{
    position P;
    int i = 0;
    for(i=0;i<H->tablesize;i++)
    {
        P = H->thelists[i]->next;
        printf("H->thelists[%d] = ",i);
        while(P != NULL)
        {
            printf("  %d",P->data);
            P=P->next;
        }
        printf("\n");   
    }
}

测试main函数

int main()
{
    int num[10] = {3,45,5,64,7,9,8,3,75,75};
    hashtable H;
    H = InitializeHashTable(10);
    int i = 0;
    for(i=0;i<10;i++)
    {   
        Insert(num[i],H);
    }
    PrintHashTable(H);
    DeleteHashTable(H);
}

头文件

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

typedef int ElementType;
typedef unsigned int index;

测试结果,可以看到图片中散列后在hash表中一样位置的都保存下来了,形成一个链表如数据75 5 45;但是相同的数据只保存一份,比如3和3,75和75
这里写图片描述
这里写图片描述

1
0
查看评论

HashTable哈希表/散列表(线性探测和二次探测)

HashTable的简单介绍HashTable是根据关键字直接访问在内存存储的数据结构。 HashTable叫哈希表或者散列表。 它通过一个关键值的函数将所需的数据直接映射到表中的位置来访问数据,这个映射函数叫散列函数(哈希函数),存放记录的数组叫散列表(哈希表)。比如: 给定一字符串“abc...
  • simplehap
  • simplehap
  • 2017-04-24 17:35
  • 670

数据结构——队列、堆栈和哈希表

本文是"考察数据结构"系列文章的第二部分,考察了三种研究得最多的数据结构:队列(Queue),堆栈(Stack)和哈希表(Hashtable)。正如我们所知,Quenu和Stack其实一种特殊的ArrayList,提供大量不同类型的数据对象的存储,只不过访问这些元素的顺序受到了限...
  • sinton
  • sinton
  • 2006-10-24 12:49
  • 2260

哈希表Hashtable与字典表Dictionary<K,V>的比较。

哈希表,名-值对。类似于字典(比数组更强大)。哈希表是经过优化的,访问下标的对象先散列过。如果以任意类型键值访问其中元素会快于其他集合。 GetHashCode()方法返回一个int型数据,使用这个键的值生成该int型数据。哈希表获取这个值最后返回一个索引,表示带有给定散列的数据项在字典中存储的位...
  • alisa525
  • alisa525
  • 2014-08-18 10:39
  • 10922

Leetcode哈希表类题目

242. Valid Anagram:Easy。unordered_map。 217. Contains Duplicate:Easy。unordered_set。 202. Happy Number:Easy。注意这里使用哈希表的方法和用途。不熟悉。 36. Valid Sudoku:Easy。利...
  • sjt091110317
  • sjt091110317
  • 2016-05-07 10:18
  • 875

c语言数据结构实现-哈希表/哈希桶(hashtable/hashbucket)

本文简单介绍了哈希表的原理,以及对内核的哈希源码进行了分析,代码里的回调思想是值得推荐的。在实际的使用中,hash表的可以用于大规模数据下的增加、删除操作;但是若存在一些遍历的需求,hash表在这块的效率不高(需要遍历所有的桶),这些情况则可以考虑别的数据结构如红黑树、B+树等;
  • stayneckwind2
  • stayneckwind2
  • 2016-12-11 18:56
  • 2315

《Redis设计与实现》阅读:Redis底层研究之哈希表hashtable

字典是一种存储键值对的抽象数据结构,其又被称为符号表(symbol table)、关联数组(associative array)或映射(map)。Redis使用字典存储键值对,而Redis在底层是通过自定义的哈希表来实现字典这一数据结构的。本文,我们将研究Redis中哈希表的实现。
  • lipeng_bigdata
  • lipeng_bigdata
  • 2016-11-29 16:15
  • 524

C语言实现 HashTable

简单实现了哈希表的插入和查找功能,简要说明如下: 1、数据结构: struct HashNode {             char* sKey;   ...
  • woxiaozhi
  • woxiaozhi
  • 2011-08-30 14:06
  • 8689

数据结构之哈希表二(用开散列法实现哈希表)

前面我们讲了哈希冲突的闭散列(开放定址法)的两种方法,现在我们来介绍另一种方法:开散列法。 通常,每个桶中的同义词子表都很短,设有n个关键码通过某一个散列函数,存放到散列表中的m个桶中,那么每一个桶中的同义词子表的平均长度为n/m。这样以搜索平均长度为n/m的同义词子表代替了搜索长...
  • hj605635529
  • hj605635529
  • 2017-04-25 12:18
  • 259

C# 哈希表Hashtable与字典表Dictionary<K,V>的比较。

Hashtable 和 Dictionary <K, V> 类型 1):单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分. 2):多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Ha...
  • heyuchang666
  • heyuchang666
  • 2016-01-12 12:45
  • 5082

HashTable 哈希表/散列

前言在前面,我们提到过了几种搜索结构的树,二叉搜索树是根据左孩子节点的值小于根节点,右孩子节点的值大于根节点而建立的,当我们把n个数据插入到二叉搜索树中,最好情况下(数据插入后是一颗完全二叉树)我们查找数据的时间复杂度为O(lg(N)),但是当我们按照一定的顺序往二叉搜索树中插入数据时,它会呈现一个...
  • bit_clearoff
  • bit_clearoff
  • 2016-11-04 20:46
  • 502
    个人资料
    • 访问:293592次
    • 积分:4553
    • 等级:
    • 排名:第7744名
    • 原创:141篇
    • 转载:41篇
    • 译文:2篇
    • 评论:85条
    我的微博
    博客专栏
    文章分类