C语言:Hash表查找字符串内容

目标:通过特定的一个哈希函数,将任意类性值映射成为一个整数值,(例如index = value % size)并将整数值作为索引,去一个顺序表中查找这个索引的value。

这种数据结构可以减少查找的时间复杂度,使之接近O(1),达不到顺序表的查找速度是因为可能会出现一个索引对应多个value,这时就要参考冲突处理机制

常见的冲突处理机制有:

  • 拉链法:最常用,即设计一个链表依次存放同一索引的value值;
  • 开放定值法:找附近不冲突的位置存放;
  • 再哈希法:设计多个哈希函数,冲突则使用下一个哈希函数,映射新的不冲突的值;
  • 公共存储区:建立一个存储区专门存放冲突的值;
  • 二次探测法:按index^2探测…

现在已经存在很多优秀的针对整形、字符型、浮点型等的哈希函数,可以直接使用。

Code

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

//拉链法
//链表节点,数据域存字符串
typedef struct Node{
	char *str;
	struct Node *next;
}Node;

//顺序表(表头,大小)
typedef struct HashTable{
	//链表首地址,是链表头结点的顺序表,由于头结点是Node *,顺序表示Node **
	Node **data;
	int size;
}HashTable;

//初始化链表,头插法,产生的新节点的next = 传入节点
Node *init_node(char *str, Node *head){
	Node *p = (Node *)malloc(sizeof(Node));
	p->str = strdup(str);//创建一片空间,需要free,万一*str内容变了也没关系
	p->next = head;
	return p;//虚拟头结点
}

HashTable *init_hashtable(int n){
	HashTable *h = (HashTable *)malloc(sizeof(HashTable));
	h->size = n << 1;//若要使哈希表存储效率变高,存储空间扩大一倍??
	h->data = (Node **)calloc(h->size, sizeof(Node *));
	return h;
}

void clear_node(Node *node){
	if (node == NULL) return;
	Node *p = node, *q;
	while(p){
		q = p->next;
		free(p->str);
		free(p);
		p = q;
	}
	free(q);//?
	return;
}

void clear_hashtable(HashTable *h){
	if (h == NULL) return;
	for (int i = 0; i < h->size; i++){
		clear_node(h->data[i]);
	}
	free(h->data);
	free(h);
	return;
}

int BKDRHash(char *str){
	int seed = 31, hash = 0;
	for (int i = 0; str[i]; i++) hash = hash * seed + str[i];
	//保证正数
	return hash & 0x7fffffff;
}

int insert(HashTable *h, char *str){
	int hash = BKDRHash(str);
	int ind = hash % h->size;
	h->data[ind] = init_node(str, h->data[ind]);
	return 1;
}

int search(HashTable *h, char *str){
	int hash = BKDRHash(str);
	int ind = hash % h->size;
	Node *p = h->data[ind];
	while (p && strcmp(str, p->str)) p = p->next;
	return p != NULL;
}

int main(){
	setvbuf(stdout, NULL, _IONBF, 0);
#define max_n 100
	int op;
	char str[max_n + 5] = {0};
	HashTable *h = init_hashtable(max_n + 5);
	while(~scanf("%d%s", &op, str)){
		switch (op){
		case 0:
			printf("insert %s to hashtable\n", str);
			insert(h, str);
			break;
		case 1:
			printf("search %s from hashtable, result = %d\n", str, search(h, str));
		}
	}
#undef max_n
	return 0;
}

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值