腾讯三面的时候,叫我写了个哈希表,当时紧张没写好···结果跪了···

  回来后粪发涂墙,赶紧写了一个!

  什么都不说了···先让我到厕所里面哭一会···

  %>_<%

  果然现场发挥,以及基础扎实才是important的!  

  用链地址法解决冲突的哈希表(C语言,VS2008编写、测试):

 #include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h> struct node {
int count; // count the same value
char *value;
node *next;
}; // 使用链地址法解决冲突
struct hash_table {
int size; // table size
node **list; // 链表队列一条链为一个散列位置
}; //==================================================//
// declare int hash_func(char *str, int tableSize);
hash_table *hash_table_init(int tableSize);
node *hash_table_new_node(char *str, int len);
int hash_table_insert(char *str, struct hash_table * head);
node *hash_table_find(char *str, struct hash_table * head);
void hash_table_clear(struct hash_table * head);
void hash_table_print(hash_table *head); //==================================================//
// realize // hash function: return the position of str in the hash table
int hash_func(char *str, int tableSize) {
unsigned int hashVal = ; while (*str != '\0')
hashVal += (hashVal << ) + *str++; return hashVal % tableSize;
} // init & create hash table
hash_table *hash_table_init(int tableSize) {
hash_table *head; head = (hash_table *)malloc(sizeof(hash_table));
if (NULL == head)
return NULL;
// 元素总数量尽可能为素数,以保证mod尽可能均匀
head->size = tableSize; // 链表队列中,一条链为一个散列位置
head->list = (node **)malloc(sizeof(node *) * tableSize); // initialize each hash list
int i;
for (i = ; i < head->size; i++)
head->list[i] = NULL; return head;
} // return one new node
node *hash_table_new_node(char *str, int len) {
node *newNode = (node *)malloc(sizeof(node));
newNode->count = ;
newNode->next = NULL;
newNode->value = (char *)malloc(len + );
memset(newNode->value, , len + );
memcpy(newNode->value, str, len); return newNode;
} // insert one node into hash table
int hash_table_insert(char *str, hash_table *head) {
int len = strlen(str);
// get str's position in the hash table
int pos = hash_func(str, head->size); printf("[insert] %s at pos: %d\n", str, pos); // locate list
node *q = head->list[pos], *p = head->list[pos];
for ( ; p != NULL; p = p->next) {
if (memcmp(p->value, str, len) == ) {
p->count++; // found the same value, count+1
return pos;
}
q = p; // store the previous node
} // if not found, then insert one new node
node *newNode = hash_table_new_node(str, len);
/*
//===================================================================//
// method 1:
// TODO: 如果是字符串不同,但是哈希值一样呢???貌似没考虑到这种情况
// insert into the head of list
newNode->next = head->list[pos];
head->list[pos] = newNode;
*/
//===================================================================//
// method 2:
// insert into the tail of list
// 由于p指向了NULL,所以要插入链表尾的话,就必须增加一个变量q记录p前一个节点位置
if (NULL == q) {
newNode->next = head->list[pos];
head->list[pos] = newNode;
} else {
q->next = newNode;
newNode->next = NULL;
} return pos;
} // find the node which stored str & return it
node *hash_table_find(char *str, hash_table *head) {
if (NULL == head)
return NULL; int pos = hash_func(str, head->size);
node *p = head->list[pos]; int len = strlen(str); for ( ; p != NULL; p = p->next)
if (memcmp(p->value, str, len) == )
break;//return p; // found & return return p; //return NULL;
} // clear the whole hash table
void hash_table_clear(hash_table *head) {
if (NULL == head)
return; node *p = NULL, *q = NULL; int i;
for (i = ; i < head->size; i++) {
p = head->list[i];
while (p != NULL) {
p->count = ; // TODO: test
q = p->next;
// free value
if (p->value) {
free(p->value);
p->value = NULL;
}
// free current node
if (p) {
free(p);
p = NULL;
}
// point to next node
p = q;
}
}
// free list
if (head->list) {
free(head->list);
head->list = NULL;
}
// free head
if (head) {
free(head);
head = NULL;
}
} // print the whole hash table
void hash_table_print(hash_table *head) {
if (NULL == head) {
printf("hash table is NULL! \n");
return;
} int i;
node *p = NULL; for ( i = ; i < head->size; i++) {
p = head->list[i];
printf("//============list %d============//\n", i);
while (p != NULL) {
if (p->value)
printf("%s:%d ", p->value, p->count);
else
printf("(NULL):(0) ");
p = p->next;
}
printf("\n");
}
} // test
int main() {
// create
hash_table *head = hash_table_init(); // insert
hash_table_insert("test 1", head);
hash_table_insert("test 2", head);
hash_table_insert("test 2", head);
hash_table_insert("test 3", head);
hash_table_insert("test 4", head); hash_table_print(head); // find
node *find = hash_table_find("test 2", head);
printf("\n[Find] %s:%d\n\n", find->value, find->count); // clear
hash_table_clear(head); hash_table_print(head); // create
head = hash_table_init(); // insert
hash_table_insert("test 1", head);
hash_table_insert("test 2", head);
hash_table_insert("test 2", head);
hash_table_insert("test 3", head);
hash_table_insert("test 4", head); hash_table_print(head); return ;
}

C语言-简单哈希表(hash table)的更多相关文章

  1. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  2. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  3. 词典(二) 哈希表(Hash table)

    散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...

  4. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  5. 什么叫哈希表(Hash Table)

    散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...

  6. 哈希表(Hash table)

  7. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

  8. Hash表 hash table 又名散列表

    直接进去主题好了. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构.也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...

  9. [译]C语言实现一个简易的Hash table(4)

    上一章我们解释了Hash table中最重要的hash函数,并用伪代码和C语言实现了一个我们自己的hash函数,hash函数中碰撞是无法避免的,当发生碰撞时我们改如何有效的处理呢?这章我们就来讲解下. ...

随机推荐

  1. Makefile笔记

    一个简单的Makefile描述规则组成: TARGET...:PREREQUISITES... COMMANDS... ... target:规则的目标.通常是程序中间或者最后要生成的文件名,也可以是 ...

  2. maven 环境搭建 Myeclipse配置

    一:Maven的下载安装 准备工作: 1)安装环境 Windows xp 2)需安装JDK ,并配置环境变量(略) 3) Maven版本3.0.5 4)下载地址:http://mirror.bit.e ...

  3. Sina App Engine(SAE)入门教程(6)- memcache使用

    Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等.简单的说就是将数据调用到内 ...

  4. 修改 eclipse 文件编码格式

    如果要使插件开发应用能有更好的国际化支持,能够最大程度的支持中文输出,则最好使 Java文件使用UTF-8编码.然而,Eclipse工作空间(workspace)的缺省字符编码是操作系统缺省的编码,简 ...

  5. shell 编程基础(1)---初识shellscript

    shellscript 是linux下强大的系统管理工具,可以通过bash命令和管道命令直接在linux系统上进行编程,所写的脚本不需要编译就可以执行,对于系统管理而言十分方便. #!/bin/bas ...

  6. Android 自定义控件-TextView

    很多时候系统自带的View满足不了设计的要求,就需要自定义View控件.自定义View首先要实现一个继承自View的类.添加类的构造方法,override父类的方法,如onDraw,(onMeasur ...

  7. MyEclipse 2014 + JSP+ Servlet

    来自:http://blog.csdn.net/21aspnet/article/details/21867241 1.安装准备 1).下载安装MyEclipse2014,这已经是最新版本. 2).下 ...

  8. java类的加载以及初始化顺序

    类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...

  9. Support Library官方教程(3)android studio中导入支援包

    Support Library Setup How you setup the Android Support Libraries in your development project depend ...

  10. jquery学习以及下载链接

    jquery学习链接 http://www.w3school.com.cn/jquery/jquery_intro.asp jquery 脚本库下载链接 http://jquery.com/downl ...