ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法学习笔记(三)——散列表

2021-09-13 20:00:24  阅读:181  来源: 互联网

标签:keys MyHash 笔记 列表 int 算法 values value key


1.1 散列表(哈希表)

  散列表(哈希表)是根据键值而直接进行访问的数据结构。通过一个散列函数将查找的键转换为表中的一个索引,来加快查找的速度。理想情况下,不同的键值都能转化为不同的索引值,但是在现实中,我们常常要处理多个键值对应同一个索引值。所以,散列查找的算法分为两个部分。第一部分就是关键的散列函数,第二部分就是处理哈希冲突。

1.2 散列函数

  散列函数就是通过该函数将元素的键值转换为表的索引。散列函数应该易于计算并且能够均匀分布所有的键,得到的散列值应该是一个非负整数,每个不同的键都有一一对应的散列值。

1.3 哈希冲突的处理

  1. 拉链法

    将表的每一个索引位置都对应一个链表,链表的每个结点都存储了对应的键值。

  2. 开放地址法

    用大小为M的数组保存N个键值对(M>N),通过依靠数组中的空位解决哈希冲突。最简单的开放地址法便是线性探测法,当碰撞发生时,我们直接检查散列表的下一个位置。此时可能有三种结果,命中,未命中或者继续查找。

2.代码实现

  1. 基于拉链法实现的散列表

    template <typename key, typename value>
    class ChainingListHashTable
    {
    private:
        int N;      //键值对数量
        int M;      //散列表的大小
        vector<vector<value>> List;
    
        int MyHash(key key)
        {
            hash<key> hash_key;
            return (hash_key(key) & 0x7ffffff % M);
        }
    public:
        ChainingListHashTable(int m)
        {
            N = 0;
            M = m;
            List.resize(m);
        }
        
        value get(key key)
        {
            return List[MyHash(key)][0];
        }
    
        void put(key key, value value)
        {
            List[MyHash(key)].push_back(value);
            N++;
        }
        
        void erase(key key)
        {
            value v = MyHash(key);
            for(int i = 0; i < List[v].size(); ++i)
            {
                if(List[v][i]==key)
                {
                    List[v].erase(List[v].begin()+i);
                    return;
                }    
            }
            cerr<<"No such key in List"<<endl;
            return;
        }
    };
    
  2. 基于线性探测法的散列表

    template <typename key, typename value>
    class LinearProbingHashTable
    {
    private:
        int N;
        static int M = 16;
        vector<key> keys;
        vector<value> values;
        int MyHash(key key)
        {
            hash<key> hash_key;
            return (hash_key(key) & 0x7ffffff % M);
        }
        void resize(int cap)
        {
            keys.resize(cap);
            values.resize(cap);
        }
    
        bool contains(key key)
        {
            for (int i = MyHash(key); keys[i] != NULL; i = (i + 1) % M)
            {
                if (keys[i] == key)
                    eturn true;
            }
            return false;
        }
    
    public:
        LinearProbingHashTable()
        {
            keys.resize(M);
            values.resize(M);
        }
    
        void put(key key, value value)
        {
            if (N >= M / 2)
                resize(2 * M);
            int i;
            for (i = MyHash(key); keys[i] != NULL; i = (i + 1) % M)
            {
                if (keys[i] == key)
                {
                    values[i] = value;
                    return;
                }
            }
            keys[i] = key;
            values[i] = value;
            N++;
        }
    
        value get(key key)
        {
            for (int i = MyHash(key); keys[i] != NULL; i = (i + 1) % M)
            {
                if (keys[i] == key)
                    return values[i];
            }
            return NULL;
        }
    
        void erase(key Key)
        {
            if (!contains(Key))
                return;
            int i = MyHash(Key);
            while (keys[i] != Key)
                i = (i + 1) % M;
            keys[i] = NULL;
            values[i] = NULL;
            i = (i + 1) % M;
            while (keys[i] != NULL)
            {
                key keyToRedo = keys[i];
                value valueToRedo = values[i];
                keys[i] = NULL;
                values[i] = NULL;
                N--;
                put(keyToRedo, valueToRedo);
                i = (i + 1) % M;
            }
            if (N > 0 && N == M / 8)
                resize(M / 2);
        }
    };
    

标签:keys,MyHash,笔记,列表,int,算法,values,value,key
来源: https://www.cnblogs.com/WiatrY/p/15264593.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有