zoukankan      html  css  js  c++  java
  • 哈希表

    代码实现

    hashTable.c文件

    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct hashNode {
        // 关键字
        char *key;
        // 关键字对应值
        void *value;
        // 指向下一个哈希节点
        struct hashNode *next;
    }hashNode;
    
    typedef struct hashTable {
        // 一个指针指向数组,数组存放指针,该指针指向哈希节点
        hashNode **table;
        unsigned long size;
    }hashTable;
    
    
    // 新建一个hash节点,新建失败返回NULL
    hashNode *newHashNode(const char *key, void *value)
    {
        hashNode *node = (hashNode*)malloc(sizeof(hashNode));
        if(node == NULL)
            return NULL;
        node->key = (char*)malloc(sizeof(char)*strlen(key) + 1);
        if(node->key == NULL) {
            free(node);
            return NULL;
        }
        strcpy(node->key, key);
        node->value = value;
        node->next = NULL;
    
        return node;
    }
    
    
    hashTable *hashCreate(int size)
    {
        hashTable *hash = (hashTable*)malloc(sizeof(hashTable));
        if(hash == NULL)
            return NULL;
    
        hash->table = (hashNode**)malloc(sizeof(hashNode*)*size);
        if(hash->table == NULL) {
            free(hash);
            return NULL;
        }
        hash->size = size;
    
        // 初始化hash数组
        for(int i=0; i<size; i++) {
            hash->table[i] = NULL;
        }
    
        return hash;
    }
    
    // 根据键值获取对于数组的index
    unsigned long hashIndex(hashTable *hash, const char *key)
    {
        unsigned long index = 0;
        while(*key)
            index = index*33 + *key++;
        return index%hash->size;
    }
    
    // 根据key查找哈希表,如果找到返回该节点,否则返回NULL
    hashNode *hashSearch(hashTable *hash, const char *key)
    {
        hashNode *node;
        unsigned long index;
        index = hashIndex(hash, key);
        for(node=hash->table[index]; node; node=node->next)
            if(!strcmp(node->key, key)) // 关键字相等
                return node;
        return NULL;
    }
    
    
    
    // 定义一个插入结点的方法,首先是查看该key值的结点是否存在
    // k如果存在则更改value值就好,如果不存在,则插入新结点。
    bool hashInsert(hashTable *hash, const char *key, void *value)
    {
        hashNode *node;
        unsigned long index;
        // 如果没找到,则新建一个节点
        if((node = hashSearch(hash, key)) == NULL) {
            // 重新获取索引值
            index = hashIndex(hash, key);
            if((node = newHashNode(key, value)) == NULL)
                return false;   // 新建内存失败
            
            // 插入对应的哈希表的链表分支头结点
            node->next = hash->table[index];
            hash->table[index] = node;
            return true;
        }
        // 对应键值已经存有节点,则键值不变,释放value旧值,指向成新的
        free(node->value);
        node->value = value;
        return true;
    }
    
    
    void *hashNodeValue(hashNode *node)
    {
        return node->value;
    }
    
    void hashRelease(hashTable *hash)
    {
        hashNode *node;
        // 释放数组中的所有链表,以及链表节点指向的内存
        for(int i=0; i<hash->size; i++) {
            while(hash->table[i] != NULL) {
                node = hash->table[i]->next;
                // 释放哈希节点所链接的内存
                free(hash->table[i]->key);
                free(hash->table[i]->value);
                // 释放节点本身
                free(hash->table[i]);
                hash->table[i] = node;
            }
        }
        // 释放指针数组
        free(hash->table);
        // 释放哈希表本身
        free(hash);
    }
    
    unsigned long hashGetTableSize(hashTable *hash)
    {
        return hash->size;
    }
    
    void printHash(hashTable *hash)
    {
        
        hashNode *node;
        for(int i=0; i<hash->size; i++) {
            printf("[%2d]-->", i);
            // 指向第一个元素
            node = hash->table[i];  
            while( node != NULL) {
                printf("[%s]-->", hash->table[i]->key);
                node = node->next;
            }
            printf("null
    
    ");
        }
    }
    

    hashTable.h文件

    #pragma once
    
    typedef struct hashNode hashNode;
    typedef struct hashTable hashTable;
    
    
    // 新建一个hash节点,新建失败返回NULL
    hashNode *newHashNode(const char *key, void *value);
    // 新建hash表
    hashTable *hashCreate(int size);
    // 根据键值获取对于数组的index
    unsigned long hashIndex(hashTable *hash, const char *key);
    // 根据key查找哈希表,如果找到返回该节点,否则返回NULL
    hashNode *hashSearch(hashTable *hash, const char *key);
    // 定义一个插入结点的方法,首先是查看该key值的结点是否存在
    // k如果存在则更改value值就好,如果不存在,则插入新结点。
    bool hashInsert(hashTable *hash, const char *key, void *value);
    // 由节点返回值
    void *hashNodeValue(hashNode *node);
    // 释放哈希链表
    void hashRelease(hashTable *hash);
    // 获取哈希表大小
    unsigned long hashGetTableSize(hashTable *hash);
    
    // 打印Hash表
    void printHash(hashTable *hash);
    

    test.c文件

    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdlib.h>
    #include "hash.h"
    
    typedef struct student {
        char name[20];
        int age;
    }student;
    
    
    void printStudent(void *stu)
    {
        student *st = (student*)stu;
        printf("name %s ", st->name);
        printf("age %d ", st->age);
        printf("
    ");
    }
    
    
    student *newStudent(const char *name, int age)
    {
        student *stu = (student *)malloc(sizeof(student));
        stu->age = age;
        strcpy(stu->name, name);
        return stu;
    }
    
    
    int main()
    {
        hashTable *hash = hashCreate(30);
    
        // 插入hash表
        hashInsert(hash, "Jim", newStudent("李苗苗", 22));
        hashInsert(hash, "Peter", newStudent("赵庄闷", 23));
        hashInsert(hash, "Mike", newStudent("林加油", 27));
        hashInsert(hash, "Docter", newStudent("梦网纱", 25));
        hashInsert(hash, "Hacker", newStudent("丁克族", 34));
        printHash(hash);
    
        hashNode *node = hashSearch(hash, "Hacker");
    
        if(node)
            printStudent(hashNodeValue(node));
    
        hashRelease(hash);
    
        printf("ret
    ");
        return 0;
    }
    
  • 相关阅读:
    Extjs杂记录
    Extjs获得组件值的方式
    Extjs选中多行Grid提交
    Extjs定时操作
    Maven自动部署Tomcat错误排除
    Eclipse下maven部署web项目到tomcat7(兼容tomcat8)
    MyEclipse 2013安装后要做的几件事
    从零开始学习SSH框架笔记之四 几个关键配置文件备忘(模板)
    虚机,操作系统启动以后,卡住不动了,按F2,出现缺失文件的内容
    chroot命令
  • 原文地址:https://www.cnblogs.com/wjundong/p/11900296.html
Copyright © 2011-2022 走看看