zoukankan      html  css  js  c++  java
  • C++:哈希

    1.基本概念

      哈希一般用来快速查找,通过hash函数将输入的键值(key)映射到某一个地址,然后就可以获得该地址的内容。

    同样,如果要储存一对值(键值和数据),则也是通过hash函数获得地址来存入。见图例:

      不过这其中会出现一些问题,最常见的是出现冲突。就是输入不同的key,经过hash之后得到同样的值,也就是在同一个地址要储存不同的data,

    例如使用上图的hash,输入的key为1和11得到的地址都是1,则这种就是出现了冲突。

      解决这种冲突的方法有多种,比如线性探测法,折叠法,链表法等等。

    2.实例

      下面是一个基于C++的简单的模板类,使用链表法来解决冲突。该hash类的数据结构为:

    struct data
        {
            size_t key;
            map_t content;
            bool isEmpty;
            data * next;
            data() :isEmpty(true), next(nullptr){}
        };

      程序:

    template<typename map_t>
    class MyHash
    {
    public:
        MyHash() :size(1000)
        {
            store = new data[size];
        }
        MyHash(size_t s) :size(s)
        {
            store = new data[size];
        }
        ~MyHash()
        {
            delete[]store;
        }
    public:
        bool insert(size_t key, map_t val);
        bool find(size_t key, map_t & val);
        bool erase(size_t key);
        void print();
    
    private:
        size_t size;
        struct data
        {
            size_t key;
            map_t content;
            bool isEmpty;
            data * next;
            data() :isEmpty(true), next(nullptr){}
        };
        
        data * store;
        size_t hash(size_t key);
    };
    
    
    template<typename map_t>
    bool MyHash<map_t>::insert(size_t key, map_t val)
    {
        size_t t_k = hash(key);
        if (t_k >= size || t_k < 0)
            return false;
        if (!store[t_k].isEmpty)
        {
            data * temp_ptr = & store[t_k];
            while (temp_ptr->next!=nullptr)
            {
                temp_ptr = temp_ptr->next;
                if (temp_ptr->key == key)
                {
                    temp_ptr->content = val;
                    return true;
                }
            }
            data *new_ = new data;
    
            new_->key = key;
            new_->content = val;
            new_->isEmpty = false;
            new_->next = nullptr;
            temp_ptr->next = new_;
    
            return true;
        }
    
        data* new_ = new data;
        new_->key = key;
        new_->content = val;
        new_->isEmpty = false;
        new_->next = nullptr;
    
        store[t_k].next = new_;
        store[t_k].isEmpty = false;
        
    
        return true;
    }
    template<typename map_t>
    bool MyHash<map_t>::find(size_t key, map_t& val)
    {
        size_t t_k = hash(key);
        if (t_k >= size || t_k < 0)
            return false;
        
            data * temp_ptr = &store[t_k];
            while (temp_ptr->next != nullptr)
            {
                temp_ptr = temp_ptr->next;
                if (temp_ptr->key == key)
                {
                    val = temp_ptr->content;
                    return true;
                }
            }
            return false;
    }
    template<typename map_t>
    bool MyHash<map_t>::erase(size_t key)
    {
        size_t t_k = hash(key);
        if (t_k >= size || t_k < 0 || store[t_k].isEmpty)
            return false;
    
        data * temp_ptr = &store[t_k];
        data * temp_ptr_ = &store[t_k];
        while (temp_ptr->next!=nullptr)
        {
            temp_ptr_ = temp_ptr;
            temp_ptr = temp_ptr->next;
            if (temp_ptr->key == key)
            {
                temp_ptr_->next = temp_ptr->next;
                delete temp_ptr;
                return true;
            }
        }
    
        return false;
    }
    template<typename map_t>
    void MyHash<map_t>::print()
    {
        for (int i = 0; i < size; ++i)
        {
            if (!store[i].isEmpty)
            {
                cout << i << "  : ";
    
                data * temp_ptr = &store[i];
                while (temp_ptr->next != nullptr)
                {
                    temp_ptr = temp_ptr->next;
                    cout << " - " << temp_ptr->content;
                }
                cout << endl;
            }
        }
    }
    
    template<typename map_t>
    size_t MyHash<map_t>::hash(size_t key)
    {
        return key%size;
    }
    ------------ 转载请注明出处 ------------
  • 相关阅读:
    gulp.js基础入门
    正则匹配
    app的meta标签
    移动端UC浏览器和QQ浏览器的部分私有meta属性
    雅虎团队经验:网站页面性能优化的 34条黄金守则
    DOCTYPE声明作用及用法详解
    DOCTYPE 中xhtml 1.0和 html 4.01区别分析
    html doctype 作用介绍
    WebStorm
    JQuery的Ajax跨域请求原理概述及实例
  • 原文地址:https://www.cnblogs.com/whlook/p/6676090.html
Copyright © 2011-2022 走看看