基于拉链法的散列表(c++版)

HashTable.h

#pragma once
#include <functional>
#include <stdexcept>
template<typename Key,typename Value,typename Hash = std::hash<Key>>
class HashTable
{
private:
    class List
    {
    public:
        class Node
        {
        public:
            Node* next = nullptr;
            Key key;
            Value value;
        public:
            Node(const Key& k, const Value& v) :key(k), value(v)
            {

            }
            ~Node()
            {
                if (next != nullptr)
                    delete next;
            }
        };
        Node* head = nullptr;
    public:
/****************************************************
函数名称:   put
函数说明:   存储key-value并判断是否更新kvcount
返回值:        bool
****************************************************/
        bool put(const Key& k, const Value& v)
        {
            if (head == nullptr)
            {
                head = new Node(k, v);
                return true;
            }
            if (head->key == k)
            {
                head->value = v;
                return false;
            }
            Node* curr = head;
            while (curr->next != nullptr)
            {
                if (curr->next->key == k)
                {
                    curr->next->value = v;
                    return false;
                }
                curr = curr->next;
            }
            curr->next = new Node(k, v);
            return true;
        }
/******************************************
函数名称:
函数说明:
返回值:
*******************************************/
        Value get(const Key& k)
        {
            Node* curr = head;
            while (curr != nullptr)
            {
                if (curr->key == k)
                    return curr->value;
                curr = curr->next;
            }
            throw std::overflow_error("can't get");
        }
/*******************************************
函数名称:   erase
函数说明:   删除key-value对应节点并判断是否删除
返回值:        void
********************************************/
        bool erase(const Key& k)
        {
            if (head == nullptr)
                return false;
            if (head->key == k)
            {
                delete head;
                head = nullptr;
                return true;
            }
            Node* curr = head;
            Node* pre = nullptr;
            while (curr->next != nullptr)
            {
                if (curr->next->key == k)
                {
                    Node* temp = curr->next;
                    curr->next = curr->next->next;
                    delete temp;
                    return true;
                }
                pre = curr;
                curr = curr->next;
            }
            if (curr->key == k)
            {
                delete curr;
                pre->next = nullptr;
                return true;
            }
            return false;
        }
    };
    List *t = nullptr;
    int kvcount = 0;    //键值对个数
    int listcount = 0; //链表个数
private:
/*******************************************
函数名称: isEmpty
函数说明: 判断哈希表是否为空
返回值:   bool
*******************************************/
    bool isEmpty()
    {
        return listcount == 0;
    }
/******************************************
函数名称:  hash
函数说明:  通过计算哈希值得到0--listcount的索引值
返回值:    int
*******************************************/
    int Myhash(const Key& k)
    {
        return (Hash()(k) & 0x7fffffff) % listcount;
    }
public :
    HashTable(int cap)
    {
        if (cap < 1)
            std::underflow_error("cap error");
        t = new List[cap];
        listcount = cap;
    }
/*******************************************
函数名称:   put
函数说明:   存储新key-value
返回值:     void
*******************************************/
    void put(const Key& k,const Value& v)
    {
        int index = Myhash(k);
        if (index > listcount - 1)
            throw std::out_of_range("index out_of_range");
        if (t[index].put(k, v))
            ++kvcount;
    }
/******************************************
函数名称:   get
函数说明:   搜索得到key对应的value
返回值:        Value
*******************************************/
    Value get(const Key& k)
    {
        int index = Myhash(k);
        if (index > listcount - 1)
            std::out_of_range("get out_of_range");
        return t[index].get(k);
    }
/******************************************
函数名称:  erase
函数说明:  在散列表里删除key-value
返回值:    void
*******************************************/
    void erase(const Key& k)
    {
        int index = Myhash(k);
        if (index > listcount - 1)
            throw std::out_of_range("erase out_of_range");
        if (t[index].erase(k))
            --kvcount;
    }
/******************************************
函数名称:  size
函数说明:  返回key-value数量
返回值:       int
*******************************************/
    int size()
    {
        return kvcount;
    }
    ~HashTable()
    {
        if (t != nullptr)
            delete[]t;
    }
};

main.cpp

#include <iostream>
#include "HashTable.h"
using namespace std;

int main()
{
    HashTable<string, int> ht(13);
    string a[] = { "Marco","Tom","Jerry","Mary","Happy","Sad","Ugly","Handsome","Cola","Thanks" };
    for (int i = 0; i < 10; ++i)
        ht.put(a[i],i);
    cout << ht.get("Tom") << endl;
    ht.erase("Marco");
    cout << "size: " << ht.size() << endl;
    try
    {
        cout << ht.get("Marco");
    }
    catch (const exception& e)
    {
        cout << e.what();
    }
    system("pause");
    return 0;
}

运行:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值