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

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

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

  %>_<%

  果然现场发挥,以及基础扎实才是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. windows下安装ubantu

        首先声明我是一个linux大菜鸟,之所以学这个,一个是好玩,另外做DL的一些软件如Caffe要在这个平台上运行,所以没事就鼓捣鼓捣.linux是一种内核,市场上支持这种内核的操作系统有uban ...

  2. QString->string->wstring->LPCWSTR

    QFileInfo info("./records.db"); std::string str = info.absoluteFilePath().toStdString(); / ...

  3. CentOS 7.0安装Nvidia驱动

    entOS 7.0 Nvidia显卡安装步骤: 1 在英伟达官网下载相应驱动 搜索出相应的驱动后,不要直接点,而是右健,Save Link as... 否则,会出现下载半天没动静的情况. 存放的路径上 ...

  4. mac root用户初始密码设置

    具体方法如下: 1)sudo su切换到root,输入的用户密码是当前用户的密码: 2)切换到root后,执行passwd root,设置root用户密码即可.

  5. 尝鲜delphi开发android/ios_环境搭建

    Delphi这又老树发新枝了,开始做终端程序开发了,这个东西的准确名字是:RAD Studio XE5,可以使用delphi和c++ builder进行终端开发. 我尽可能讲啰嗦一些,免得回头被人问. ...

  6. excel文档

    1.快速统计行数(ctrl+Shift+(方向键向下)). bson数据类型 留个影响 public enum BsonType { Double = 0x01, String = 0x02, Doc ...

  7. Android权限安全(13)4.3前后root原理不同

    在JB MR2(4.3)之前 Apk内部可以通过Java的Runtime执行一个具有Root-setUID的可执行文件而 提升Effective UID来完成一些特权操作,典型的Root包中的su就是 ...

  8. Android开发之LocationManager和定位

    代码: /* * 获取当前的位置,并通过短信发送位置到指定号码 */ public class LocationService extends Service { private LocationMa ...

  9. iphone 如何清空UIWebView的缓存

      iphonecachingapplicationcookiescacheperformance I actually think it may retain cached information ...

  10. linux - 开机启动thunderbird、chromium

    cd ~/.config/autostart/(没有autostart,自己 mkdir autostart) vim thunderbird.desktop,输入以下: [Desktop Entry ...