//节点类 struct LISTNODE { int n_value ; int count; char *str_value ; LISTNODE * p_next ; }; //哈希表 struct HASHTABLE { int n_tablesize ; LISTNODE ** p_node ; }; void hashtable_clear(HASHTABLE* head_ht); LISTNODE* hashtable_find(char *str ,HASHTABLE* head); int hashtable_hash(char* str, int tablesize); HASHTABLE * hashtable_init( int table_size ); LISTNODE * hashtable_newnode(char* str , int len); int hashtable_insert(char * str, HASHTABLE * head); //初始化 HASHTABLE * hashtable_init( int table_size ) { //表头 HASHTABLE * head_ht ; head_ht = (HASHTABLE *)malloc( sizeof(HASHTABLE )); if(head_ht == NULL) return NULL ; //元素总数尽量素数保证mod尽可能均匀 head_ht->n_tablesize = table_size; //链表队列一条链为一个散列位置 head_ht->p_node = (LISTNODE **) malloc(sizeof (LISTNODE*) * table_size); //每一个散列链初始化 for(int i=0; i<head_ht ->n_tablesize; i++) { head_ht->p_node[i] = NULL; } return head_ht ; } //清理 void hashtable_clear (HASHTABLE* head_ht) { if(head_ht == NULL) return; //每一个散列链free for(int i=0; i<head_ht ->n_tablesize; i++) { if(head_ht ->p_node[ i]) { LISTNODE *list = head_ht->p_node[i]; //当前链表不空 while(list != NULL) { //取得下一个 LISTNODE *tempnode = list-> p_next; //free当前字符串指针 if(list ->str_value) { free(list ->str_value); list->str_value = NULL; } //free当前位置 if(list ) free(list ); //指向下一个 list = tempnode ; } } } //链表队列free if(head_ht ->p_node) { free(head_ht ->p_node); head_ht->p_node = NULL; } //哈希头节点free if(head_ht ) { free(head_ht ); head_ht = NULL ; } } //哈希函数 //得到字符串在哈希表中的位置 int hashtable_hash (char* str, int tablesize) { unsigned int hash_val = 0; while(*str != '\0') hash_val += (hash_val << 5) + *str++; int pos = hash_val % tablesize; return pos ; } //拿到这个字符串存在的节点 LISTNODE * hashtable_find( char *str ,HASHTABLE* head) { //哪一条链表 LISTNODE * list = NULL; if(head == NULL) return NULL ; int pos = hashtable_hash(str,head-> n_tablesize); list = head ->p_node[pos]; //链表查找 while(list != NULL) { if(memcmp (str, list->str_value ,strlen( str)) == 0) break; list = list ->p_next; } return list ; } //得到新一个新节点 LISTNODE * hashtable_newnode( char* str , int len) { //插入节点初始化 LISTNODE *insert_node =(LISTNODE*) malloc(sizeof (LISTNODE)); insert_node->p_next = NULL; insert_node->count = 1; insert_node->str_value =(char*) malloc(len +1); memset(insert_node ->str_value,0, len+1); memcpy(insert_node ->str_value, str,len ); return insert_node ; } int hashtable_insert (char * str, HASHTABLE * head) { //拿到哈希位置 int pos = hashtable_hash( str,head ->n_tablesize); int len = strlen( str); printf("[insert] %s pos:%d\n",str,pos); //拿到插入的链表 LISTNODE *list_pos = head-> p_node[pos]; //假如存在 计数器+1 for(;list_pos!=NULL;list_pos=list_pos->p_next) { if(memcmp(list_pos->str_value,str,strlen(str)) == 0) { list_pos->count++; return pos; } } //不存在 LISTNODE *node = hashtable_newnode(str,strlen(str)); node->p_next = head-> p_node[pos]; head-> p_node[pos] = node; return pos ; } int main (void) { HASHTABLE * head ; //初始一个个链表的哈希表 size最好为素数 head = hashtable_init (1001); //插入一个字符串"12345"返回值为插入链表位置 hashtable_insert("12345" ,head); hashtable_insert("12345" ,head); hashtable_insert("12345" ,head); //找到这个字符串具体位置 LISTNODE * node = hashtable_find( "12345",head ); if(node != NULL) printf("str:%s count:%d",node->str_value,node->count); //清理 hashtable_clear(head ); return 0; }