• 数据结构之散列表的实现


    1. 之前研究STL源码的时候发现哈希Table底层是实现看起来实现的非常的简洁,觉得自己去写一个哈希表肯定也是很简单的。但是,但是,但是我今天看了一下数据结构里面的哈希表的简单实现,才发现其实也是有很多学问在里面的,所以今天就打算自己实现一下,做一个记录,方便以后自己来查看学习。
    2. 因为哈希表是会产生哈希冲突的嘛,一般的解决方法都是采用开链法,所以今天就简单的实现一个开链法的具体步骤。
    3. 具体步骤
      1.   先是写一个简单的模板类的框架
        #include <iostream>
        #include <list>
        #include <vector>
        #include <string.h>
        using namespace std;
        template <typename Object>
        class HashTable{
        public:
            explicit HashTable(int hashsize = 101);
        
            bool constains(const Object & x)const;
        
            void makeEmpty();
            void insert(const Object & x);
            void remove(const Object & x);
        
        private:
            int CurrentSize;
            vector < list<Object> > theLists;//这个是vector加上list的格式
        
            void ReHash();
            int MyHash (const Obeject & a) const;
        };
        int hash (const string & x);
        int hash (int key);

         这个框架还是比较通俗的,但是由于编辑工具不是很好用(linux下面的编辑工具有点bug,老是闪退,我就么有建工程,将就看吧)。主要就是实现了一下插入,删除,包含核哈希函数的构造这几个简单的方法。下面是这几个函数的具体实现代码。

      2.     void ReHash(){
        
            }
            int MyHash (const Obeject & a) const{
                int hashval = hash(x);
        
                hashval %= theLists.size();
                if (hashval < 0)
                    hashval += theLists.size();
                return hashval;
            }
        
                void makeEmpty(){
                for ( int i = 0; i< theLists.size(); i++)
                    theLists[i].clear();
            }
            bool insert(const Object & x){
                list<Object> &list1 = theLists[ MyHash(x) ];
                if (find ((list1.begin(), list1.end(), x) != list1.end()))
                    return false;
        
                list1.push_back(x);
                if (++CurrentSize > theLists.size())
                    ReHash();
                return true;
            }
            bool remove(const Object & x){
                /*移除就是找到了对应的*/
                list<Object> &list1 = theLists[ MyHash(x) ];
                list<Object> ::iterator iter = find (list1.begin(), list1.end(), x);
        
                if ( iter == list1.end() )
                    return false;
        
                list1.erase(iter);
                --CurrentSize;
                return true;
            }
                bool constains(const Object & x)const{
                /*这个就是相当于找到了对应的链表,再去链表中找到对应的实值*/
                const list<Object> &list1 = theLists[ MyHash(x) ];
                return find ((list1.begin(), list1.end(), x) != list1.end())
            }

         这个就是实现简单的带有链表和vector的哈希表了,这个比较常见。

      3.   当然还有不使用链表的哈希表。
        1.   这样的链表的解决冲突的方式有许多种
          1.   线性探测,根据键值,调用哈希函数找到对应的键值,如果该位置已经满了,就依次向后移动一个位置,知道找到末尾还是满了,就从头部开始向后找起,直到找到一个空的可以插入的位置。
          2.   平方探测,这个和上面类似,但是它每次移动的位置是当前移动次数的平方倍数。这个随机性比较大。
          3.   关于这一类的哈希表的实现我自己感觉应该是比上面的那种简单些,实现方式大多是类似的。最主要的还是去检测当前位置是否满,然后移动的规则的一些算法。

      4.   STL中的散列表还有一些其他类型的。比如hash_set,hash_map;感兴趣可以去看些STL源码。
  • 相关阅读:
    解决pandas_datareader的get_data_yahoo不能读取数据的问题
    python 中使用pandas_datareader 报错 ImportError: cannot import name ‘is_list_like’
    loc、iloc、ix 区别
    利用list元素求和组成某一个固定值
    测试id
    Oracle数据库从入门到精通 多表查询知识以及范例
    Oracle数据库从入门到精通 单行函数问题
    Oracle从入门到精通 限定查询和排序查询的问题
    关于Oracle中sys、system和Scott用户下的数据库连接问题
    Java学习笔记——关于位运算符的问题
  • 原文地址:https://www.cnblogs.com/Kobe10/p/6066368.html
Copyright © 2020-2023  润新知