散列表

抽象类dictionary.h:

#pragma once

#include <iostream>
#include <utility>

template<class K, class E>
class dictionary {
public:
    virtual ~dictionary() {}

    virtual bool empty() const = 0;

    virtual int size() const = 0;

    virtual std::pair<const K, E> *find(const K &) const = 0;

    virtual void erase(const K &) = 0;

    virtual void insert(const std::pair<const K, E> &) = 0;
};

hash函数hash.h:

#pragma once

#include <string>
#include <iostream>

template<class T>
class Hash;

template<>
class Hash<std::string> {
public:
    size_t operator()(const std::string theKey) const {
        unsigned long hashValue = 0;
        int length = (int) theKey.length();
        for (int i = 0; i < length; i++)
            hashValue = 5 * hashValue + theKey.at(i);

        return size_t(hashValue);
    }
};

template<>
class Hash<int> {
public:
    size_t operator()(const int key) const {
        return size_t(key);
    }
};

template<>
class Hash<short> {
public:
    size_t operator()(const short key) const {
        return size_t(key);
    }
};

template<>
class Hash<long> {
public:
    size_t operator()(const long key) const {
        return size_t(key);
    }
};

template<>
class Hash<long long> {
public:
    size_t operator()(const long long key) const {
        return size_t(key);
    }
};

链表实现散列表hashChain.h:

#pragma once

#include "dictionary.h"
#include "hash.h"
#include "SortedChain.h"


template<class K, class E>
class hashChain : public dictionary<K, E> {
public:
    hashChain(int theDivisor = 11);

    ~hashChain() {
        delete[]table;
    }

    bool empty() const { return dSize == 0; }

    int size() const { return dSize; }

    std::pair<const K, E> *find(const K &) const;

    void insert(const std::pair<const K, E> &);

    void erase(const K &);

protected:
    SortedChain<K, E> *table;
    Hash<K> hash;
    int divisor;
    int dSize;
};

template<class K, class E>
hashChain<K, E>::hashChain(int theDivisor) {
    divisor = theDivisor;
    dSize = 0;
    table = new SortedChain<K, E>[divisor];
}

template<class K, class E>
std::pair<const K, E> *hashChain<K, E>::find(const K &theKey) const {
    return table[hash(theKey) % divisor].find(theKey);
}

template<class K, class E>
void hashChain<K, E>::insert(const std::pair<const K, E> &thePair) {
    int homeBucket = (int) hash(thePair.first) % divisor;
    int homeSize = table[homeBucket].size();
    table[homeBucket].insert(thePair);
    if (table[homeBucket].size() > homeSize)
        dSize++;
}

template<class K, class E>
void hashChain<K, E>::erase(const K &theKey) {
    table[hash(theKey) % divisor].erase(theKey);
}

template<class K, class E>
std::ostream &operator<<(std::ostream &out, const hashChain<K, E> &x) {
    x.output(out);
    return out;
}

开放式寻址hashTable.h:

#pragma once

#include "hash.h"

template<class K, class E>
class hashTable {
public:
    hashTable(int theDivisor = 11);

    ~hashTable() { delete[]table; }

    bool empty() const { return dSize == 0; }

    int size() const { return dSize; }

    std::pair<const K, E> *find(const K &) const;

    void insert(const std::pair<const K, E> &);

    void output(std::ostream &out) const;

    int get_position(const K &theKey);

    void erase(const K &theKey);

protected:
    Hash<K> hash;
    std::pair<const K, E> **table;
    int divisor;
    int dSize;

    int search(const K &) const;
};

template<class K, class E>
int hashTable<K, E>::get_position(const K &theKey) {
    for (int i = 0; i < divisor; ++i) {
        if (table[i] != nullptr && table[i]->first == theKey)
            return i;
    }
    return -1;
}

template<class K, class E>
void hashTable<K, E>::erase(const K &theKey) {
    int b = hash(theKey) % divisor, cnt = 0;
    if (table[b] == nullptr)
        throw "error";
    bool ok = false;
    //ok 是否存在
    if (table[b]->first == theKey) {
        ok = true;
    } else {
        for (int i = (b + 1) % divisor; i != b; i = (i + 1) % divisor) {
            if (table[i]->first == theKey) {
                b = i;
                ok = true;
                break;
            }
        }
    }
    if (!ok)
        throw "error";
    delete table[b];
    table[b] = nullptr;
    dSize--;

    for (int i = b + 1; i < divisor; ++i) {
        if (table[i] == nullptr)
            return;
        if (hash(table[i]->first) % divisor <= b || hash(table[i]->first) % divisor > i) {
            table[b] = new std::pair<const K, E>(std::make_pair(table[i]->first, table[i]->first));
            delete table[i];
            table[i] = nullptr;
            cnt++;
            b = i;
        }
    }

    bool flag = false;
    for (int i = 0; i < divisor; ++i) {
        if (table[i] == nullptr)
            return;
        if (hash(table[i]->first) % divisor > i && hash(table[i]->first) % divisor <= b) {
            table[b] = new std::pair<const K, E>(std::make_pair(table[i]->first, table[i]->first));
            delete table[i];
            table[i] = nullptr;
            b = i;
            ++cnt;
            flag = true;
            break;
        }
    }

    if (!flag)return;

    for (int i = b + 1; i < divisor; ++i) {
        if (table[i] == nullptr)return;
        if (hash(table[i]->first) % divisor <= b || hash(table[i]->first) % divisor > i) {
            table[b] = new std::pair<const K, E>(std::make_pair(table[i]->first, table[i]->first));
            delete table[i];
            table[i] = nullptr;
            b = i;
            ++cnt;
        }
    }
}

template<class K, class E>
hashTable<K, E>::hashTable(int theDivisor) {
    divisor = theDivisor;
    dSize = 0;
    table = new std::pair<const K, E> *[divisor];
    for (int i = 0; i < divisor; ++i) {
        table[i] = nullptr;
    }
}

template<class K, class E>
int hashTable<K, E>::search(const K &theKey) const {
    int i = (int) hash(theKey) % divisor;
    int j = i;
    do {
        if (table[j] == nullptr || table[j]->first == theKey)return j;
        j = (j + 1) % divisor;
    } while (j != i);
    return j;
}

template<class K, class E>
std::pair<const K, E> *hashTable<K, E>::find(const K &theKey) const {
    int b = search(theKey);
    if (table[b] == nullptr || table[b]->first != theKey)
        return nullptr;
    return table[b];
}

template<class K, class E>
void hashTable<K, E>::insert(const std::pair<const K, E> &thePair) {
    int b = search(thePair.first);
    if (table[b] == nullptr) {
        table[b] = new std::pair<const K, E>(thePair);
        dSize++;
    } else {
        if (table[b]->first == thePair.first)
            table[b]->second = thePair.second;
        else throw "full";
    }
}

template<class K, class E>
void hashTable<K, E>::output(std::ostream &out) const {
    for (int i = 0; i < divisor; i++) {
        if (table[i] == nullptr) {
            std::cout << "nullptr" << std::endl;
        } else {
            std::cout << table[i]->first << " " << table[i]->second << std::endl;
        }
    }
}

template<class K, class E>
std::ostream &operator<<(std::ostream &out, const hashTable<K, E> &x) {
    x.output(out);
    return out;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值