zoukankan      html  css  js  c++  java
  • 数据结构之散列表的实现

    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源码。
  • 相关阅读:
    20175318 2018-2019-2 实验一《Java开发环境的熟悉》实验报告
    修改 IntelliJ IDEA 默认配置路径
    《Java程序设计》 第三周学习任务
    计算机网络第七版(谢希仁著)课后习题答案
    VMware虚拟机安装苹果Mac OS
    使用Xshell在Windows系统和Linux系统之间进行文件传输
    python:常用模块
    python:模块
    python:函数
    python字符编码与转码
  • 原文地址:https://www.cnblogs.com/Kobe10/p/6066368.html
Copyright © 2011-2022 走看看