zoukankan      html  css  js  c++  java
  • 哈希表的简单实现【链地址法解决冲突】

    //节点类
    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;
    }
  • 相关阅读:
    RF运行之后控制信息日志显示乱码(解决方法)
    robot framework error: [ ERROR ] Suite 'XXX' contains no tests or tasks.(解决方法)
    MySQL下载与安装
    巧妙利用selenium中的JS操作来处理特殊的文本框
    Fiddler请求图标含义
    类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法
    python模块与包的详解
    python字典总结
    python文件读写详解
    python类和self解析
  • 原文地址:https://www.cnblogs.com/guyan/p/2661891.html
Copyright © 2011-2022 走看看