C++数据结构与算法——哈希表实现(链式法)

解决散列冲突

    • 文件结构
    • 字典类
      • 概念
      • 代码
    • 哈希类
      • 概念
      • 代码
    • 有序链表
      • 概念
      • 代码
    • 哈希表实现
      • 概念
      • 代码
    • 测试主函数
      • 代码
      • 输出

文件结构

C++数据结构与算法——哈希表实现(链式法)_第1张图片

字典类

概念

代码

//dictionary.h
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& theKey)const = 0;
    virtual void erase(const K& theKey) = 0;
    virtual void insert(const std::pair<const K, E>& thePair) = 0;
};

哈希类

概念

代码

//hash.h
#pragma once
#include 
//hash类
template<class K> class hash;

template<>
class hash<std::string>
{
public:
    std::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 = hashValue * 5 + theKey.at(i);
        }
        return std::size_t(hashValue);
    }
};

template<>
class hash<int>
{
public:
    std::size_t operator() (const int theKey) const{
        return std::size_t(theKey);
    }
};

template<>
class hash<long>
{
public:
    std::size_t operator() (const long theKey) const{
        return std::size_t(theKey);
    }
};

有序链表

概念

代码

//sortedChain.h
#pragma once
#include 

//pairNode
template<class K, class E>
struct pairNode{
    std::pair<const K, E> element;
    pairNode<K, E>* next;
    pairNode(const std::pair<const K, E>& thePair)
        :element(thePair) {}
    pairNode(const std::pair<const K, E>& thePair, pairNode<K, E>* theNext)
        :element(thePair) { this->next = theNext; }
};

//sortedChain类
template<class K, class E>
class sortedChain
{
private:
    pairNode<K,E>* firstNode;
    int dSize;
public:
    sortedChain();
    ~sortedChain();
    bool isEmpty() const;
    int size() const;
    std::pair<const K, E>* find(const K& theKey) const;
    void insert(const std::pair<const K, E>& thePair);
    void erase(const K& theKey);
    void printChain(std::ostream &out) const;
};

template<class K, class E>
sortedChain<K, E>::sortedChain(){
    this->firstNode = nullptr;
    this->dSize = 0;
}

template<class K, class E>
sortedChain<K, E>::~sortedChain(){
    pairNode<K, E>* tempNode;
    while(this->firstNode){
        tempNode = this->firstNode->next;
        delete this->firstNode;
        this->firstNode = tempNode;
    }
}

template<class K, class E>
bool sortedChain<K, E>::isEmpty() const{
    return this->dSize == 0;
};

template<class K, class E>
int sortedChain<K, E>::size() const{
    return this->dSize;
};

template<class K, class E>
std::pair<const K, E>* sortedChain<K, E>::find(const K& theKey) const{
    pairNode<K, E>* tempNode = firstNode;

    //遍历
    while((tempNode != nullptr) 
        && (tempNode->element.first != theKey)){
            tempNode = tempNode->next;
    }

    //找到了
    if((tempNode != nullptr) 
        && (tempNode->element.first == theKey)){
            return &tempNode->element;
    }

    //没找到
    return nullptr;
};

template<class K, class E>
void sortedChain<K, E>::insert(const std::pair<const K, E>& thePair){
    pairNode<K, E>* afterInsertNode = this->firstNode;
    pairNode<K, E>* beforeInsertNode = nullptr;
    //遍历
    while((afterInsertNode != nullptr) 
        && (afterInsertNode->element.first < thePair.first)){
            beforeInsertNode = afterInsertNode;
            afterInsertNode = afterInsertNode->next;
    }
    //如果找到键已经存在的pairNode
    if((afterInsertNode != nullptr)
        && (afterInsertNode->element.first == thePair.first)){
            afterInsertNode->element.second = thePair.second;
            return;
    }
    //如果键还不存在,插入新节点
    pairNode<K, E>* insertNode = new pairNode<K, E>(thePair, afterInsertNode);
    if(beforeInsertNode == nullptr){//如果在头节点插入
        this->firstNode = insertNode;
    }else{
        beforeInsertNode->next = insertNode;
    }
    this->dSize++;
};

template<class K, class E>
void sortedChain<K, E>::erase(const K& theKey){
    pairNode<K, E>* eraseNode = this->firstNode;
    pairNode<K, E>* beforeEraseNode = nullptr;

    //遍历
    while((eraseNode != nullptr)
        &&(eraseNode->element.first < theKey)){
            beforeEraseNode = eraseNode;
            eraseNode = eraseNode->next;
    }
    //找到了
    if((eraseNode != nullptr)
        && (eraseNode->element.first == theKey)){
        //如果删除的是头节点
        if(beforeEraseNode == nullptr){
            this->firstNode = eraseNode->next;
        }else{
            beforeEraseNode->next = eraseNode->next;
        }
        delete eraseNode;
        this->dSize--;
    }
};

template<class K, class E>
void sortedChain<K, E>::printChain(std::ostream& out) const{
    for(pairNode<K, E>* tempNode = this->firstNode; tempNode != nullptr; tempNode = tempNode->next){
       	out << "key: " << tempNode->element.first;
       	out << ", value: " << tempNode->element.second;
       	out << "  ";
    }
    out << std::endl;
};

template<class K,class E>
std::ostream& operator<<(std::ostream& out, const sortedChain<K, E>& theChain){
    theChain.printChain(out);
    return out;
}

哈希表实现

概念

代码

//hashChains.h
#pragma once
#include "dictionary.h"
#include "hash.h"
#include "sortedChain.h"

template<class K, class E>
class hashChains : public dictionary<K, E>
{
private:
    sortedChain<K, E>* table;
    hash<K> myHash;//将关键字映射为一个整数
    int dSize;//哈希表大小
    int divisor = 11;//哈希函数的除数

public:
    hashChains(int theDivisor);
    ~hashChains();
    bool empty() const override;
    int size() const override;
    std::pair<const K, E>* find(const K& theKey)const override;
    void erase(const K& theKey) override;
    void insert(const std::pair<const K, E>& thePair) override;
    void printHashChain(std::ostream& out) const;
};

template<class K, class E>
hashChains<K, E>::hashChains(int theDivisor){
    this->divisor = theDivisor;
    this->dSize = 0;
    this->table = new sortedChain<K, E>[theDivisor];
}

template<class K, class E>
hashChains<K, E>::~hashChains(){
    if(this->table){
        delete[] this->table;
    }
}

template<class K, class E>
bool hashChains<K, E>::empty() const{
    return (this->dSize == 0);
}

template<class K, class E>
int hashChains<K, E>::size() const{
    return this->dSize;
}

template<class K, class E>
std::pair<const K, E>* hashChains<K, E>::find(const K& theKey)const{
    int bucketIndex = myHash(theKey) % this->divisor;
    return this->table[bucketIndex].find(theKey);
}

template<class K, class E>
void hashChains<K, E>::erase(const K& theKey){
    int bucketIndex = myHash(theKey) % this->divisor;
    return this->table[bucketIndex].erase(theKey);
}

template<class K, class E>
void hashChains<K, E>::insert(const std::pair<const K, E>& thePair){
    int bucketIndex = myHash(thePair.first) % this->divisor;
    //如果新增
    if(!this->table[bucketIndex].find(thePair.first)){
        this->dSize++;
    }
    this->table[bucketIndex].insert(thePair);
}

template<class K, class E>
void hashChains<K, E>::printHashChain(std::ostream& out) const{
    for(int i = 0; i < this->divisor; ++i){
        if(this->table[i].isEmpty()){
            std::cout << "NULL" << std::endl;
        }else{
            std::cout << this->table[i];
        }
    }
}

template<class K, class E>
std::ostream& operator<<(std::ostream& out, const hashChains<K, E>& theHashChains){
    theHashChains.printHashChain(out);
    return out;
}

测试主函数

代码

//main.cpp
#include 
#include 
#include "hashChains.h"

using namespace std;
int main(){
    hashChains<string, int> myHashChains1(11);
    myHashChains1.insert(pair<string, int>("abc", 2));
    myHashChains1.insert(pair<string, int>("def", 3));
    myHashChains1.insert(pair<string, int>("ghi", 4));
    myHashChains1.insert(pair<string, int>("jkl", 5));
    myHashChains1.insert(pair<string, int>("mno", 6));
    myHashChains1.insert(pair<string, int>("pqrs", 7));
    myHashChains1.insert(pair<string, int>("tuv", 8));
    myHashChains1.insert(pair<string, int>("wxyz", 9));

    hashChains<int, int> myHashChains2(11);
    myHashChains2.insert(pair<int, int>(1, 1));
    myHashChains2.insert(pair<int, int>(2, 2));
    myHashChains2.insert(pair<int, int>(3, 3));
    myHashChains2.insert(pair<int, int>(5, 5));
    myHashChains2.insert(pair<int, int>(11, 11));
    myHashChains2.insert(pair<int, int>(13, 13));
    myHashChains2.insert(pair<int, int>(10, 10));

    cout << myHashChains1 << endl << endl;
    cout << myHashChains2 << endl;

    return 0;
}

输出

C++数据结构与算法——哈希表实现(链式法)_第2张图片
一个sortedChain在同一行显示。

你可能感兴趣的:(学习笔记,数据结构,算法,c++,散列表)