hashtable模板的简单实现

hashtable模板的简单实现

知识标签: hashtable, template, 函数指针, hash, C++, container, C++11

转载注明链接出处

代码中有注释,直接上代码:

hashtable.h如下:

#ifndef __HASHTABLE_H__
#define __HASHTABLE_H__

#include<vector>
#include<list>

template<typename T>
class hashtable
{
    public:

        typedef size_t (*HT)(const T&);

        //构造函数,初始化list数组大小,hashtable元素个数,哈希函数
        //参数numLists = 100一定要放后面,因为它有默认值
        hashtable(HT ht, size_t numLists = 100) : TLists(numLists), m_num(0), phash(ht){}

        ~hashtable(){}

        bool isin(const T& t)
        {//判断t是否在hashtable中
            std::list<T>& alist = TLists[myhash(t)];
            if(alist.end() == contain(t))
                return false;
            else
                return true;
        }

        //插入一个hashtable中不存在的值
        bool insert_unique(T& t)
        {
            std::list<T>& alist = TLists[myhash(t)];
            if(contain(t) != alist.end())
            {
                return false;
            }

            insert(t);
        }

        //插入一个hashtable中可能存在的值,不检查唯一性
        void insert(T& t)
        {
            //负载系数(loading factor),意指元素个数除以表格大小。此负载系数不大于1
            //如果当前hashtable中元素个数大于vector的大小
            if(m_num + 1 > TLists.size())
            {
                resize2();
            }

            //这句代码不能写在if上面
            std::list<T>& alist = TLists[myhash(t)];
            alist.push_back(t);
            ++m_num;
        }

        //删除一个元素
        bool remove(const T& t)
        {
            std::list<T>& alist = TLists[myhash(t)];
            typename std::list<T>::iterator iter = contain(t);
            if(iter == alist.end())
            {
                return false;
            }
            else
            {
                alist.erase(iter);
                --m_num;
                return true;
            }
        }

        //清空hashtable
        bool clear()
        {
            typename std::vector<std::list<T> >::iterator iter = TLists.begin();
            //遍历list数组
            while(iter != TLists.end())
            {
                (*iter++).clear();
            }
            m_num = 0;
        }

        //依次打印hashtable所有元素
        void show()
        {
            typename std::vector<std::list<T> >::iterator i = TLists.begin();
            typename std::list<T>::iterator j;
            while(i != TLists.end())
            {
                j = (*i).begin();
                while(j != (*i).end())
                {
                    //注:T类型必须支持operator<<
                    std::cout << *j++ << '\t' << std::flush;
                }
                std::cout << std::endl;
                ++i;
            }

            std::cout << "m_num = " << m_num << std::endl;
            std::cout << "TLists.size() : " << TLists.size() << std::endl;
        }

    private:

        //list数组, hashtable存储结构
        std::vector<std::list<T> > TLists;
        size_t m_num;   //hashtable中元素个数

        //函数指针,类型T的hash函数
        size_t (*phash)(const T&);

    private:

        //判断t是否在hashtable中
        typename std::list<T>::iterator contain(const T& t)
        {
            std::list<T>& alist = TLists[myhash(t)];

            typename std::list<T>::iterator iter= alist.begin();
            while(iter != alist.end())
            {
                //注意:类型T必须有==运算符
                if(t == *iter)
                {
                    return iter;
                }
                ++iter;
            }
            return alist.end();
        }

        //hashtable自增长为原先2倍大小
        void resize2()
        {
            //备份
            std::vector<std::list<T> > oldLists = TLists;
            //扩容
            TLists.resize(2 * TLists.size());
            typename std::vector<std::list<T> >::iterator iter_new = TLists.begin();
            while(iter_new != TLists.end())
            {
                (*iter_new++).clear();
            }
            m_num = 0;

            //遍历hashtable,把所有元素插入新hashtable
            typename std::vector<std::list<T> >::iterator i = oldLists.begin();
            typename std::list<T>::iterator j;
            while(i != oldLists.end())
            {
                j = (*i).begin();
                while(j != (*i).end())
                {
                    insert(*j++);
                }
                ++i;
            }
        }

        size_t myhash(const  T& t)
        {//返回list数组下标
            size_t val_hash = phash(t);
            val_hash = val_hash % TLists.size();
            return val_hash;
        }
};

#endif

main.cpp文件如下:

#include<iostream>
#include<string>
#include<functional>
#include "hashtable.h"

class node
{
    public:

        node(std::string st, size_t sc)
        {
            str = st;
            score = sc;
        }

        friend std::ostream& operator<<(std::ostream& fout, node nd);
        friend bool operator==(node nd1, node nd2);

        std::string str;
        size_t score;
};

std::ostream& operator<<(std::ostream& out, node nd)
{
    out << "( " << nd.str << ", " << nd.score << " )";
}

bool operator==(node nd1, node nd2)
{
    if(nd1.str == nd2.str)
    {
        return true;
    }
    else
    {
        return false;
    }
}

size_t myhash(const node& nd)
{
    //利用string字段返回hash值
    return std::hash<std::string>()(nd.str);
}

int main(void)
{
    hashtable<node> ht(&myhash, 6);

    node nd1("小明", 66);
    node nd2("小花", 77);
    node nd3("小红", 88);
    node nd4("小王", 56);
    node nd5("小李", 99);
    node nd6("小时", 100);
    node nd7("小周", 90);
    node nd8("小郭", 67);
    node nd9("小吴", 87);
    node nd10("小马", 79);
    node nd11("小黄", 92);

    ht.insert(nd1);
    ht.insert(nd2);
    ht.insert(nd3);
    ht.insert(nd4);
    ht.insert(nd5);
    ht.insert(nd6);
    ht.insert(nd7);
    ht.insert(nd8);
    ht.insert(nd9);
    ht.insert(nd10);
    ht.insert(nd11);
    ht.show();

    std::cout << "----------------------------" << std::endl;
    ht.remove(nd3);
    if(ht.isin(nd3))
        std::cout<< "nd3 is in hashtable !" << std::endl;
    else
        std::cout << "nd3 is not in hashtable !" << std::endl;

    std::cout << "----------------------------" << std::endl;
    ht.clear();
    ht.show();

    return 0;
}

编译如下:

g++ main.cpp -o main -std=c++11

我在代码中用到了C++11标准,所以编译时添加-std=c++11

结果截屏:
hashtable结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值