c++实现hash数据库

本程序实现了一个可以插入任意数据对象的c++实现的hash数据库支持增删改查
同时采用了拉链法处理冲突.
接下来我们一起看实现吧

key-value数据库存储单元类型

第一步首先实现一个基础的key-value类型

//field.h
#pragma once
#include <iostream>
class field
{
private:
    std::string *key;
    void *value;

public:
    std::string *getKey();
    void *getValue();
    void setValue(void *v);
    field();
    field(std::string *k);
    field(std::string *k, void *v);
    ~field();
};
//field.cpp
#include "field.h"
std::string *field::getKey()
{
    return key;
}
void *field::getValue()
{
    return value;
}
void field::setValue(void *v)
{
    value = v;
}
field::field() : key(NULL), value(NULL) {}
field::field(std::string *k) : key(k), value(NULL) {}
field::field(std::string *k, void *v) : key(k), value(v) {}
field::~field()
{
    delete key;
    delete value;
}

基于key-value类型的双向链表节点

随后构建一个在类型基础之上的双向链表节点

//doubleLinkedNode.h
#pragma once
#include "field.h"
class doubleLinkedNode
{
private:
    doubleLinkedNode *left;
    doubleLinkedNode *right;
    field *data;

public:
    doubleLinkedNode *getLeft();
    doubleLinkedNode *getRight();
    field *getData();

    void setLeft(doubleLinkedNode *p);
    void setRight(doubleLinkedNode *p);
    void setData(void *v);

    doubleLinkedNode();
    doubleLinkedNode(field *v);
    doubleLinkedNode(std::string *k);
    doubleLinkedNode(std::string *k, void *v);

    ~doubleLinkedNode();
};
//doubleLinkedNode.cpp
#include "doubleLinkedNode.h"
doubleLinkedNode *doubleLinkedNode::getLeft()
{
    return left;
}
doubleLinkedNode *doubleLinkedNode::getRight()
{
    return right;
}
field *doubleLinkedNode::getData()
{
    return data;
}
void doubleLinkedNode::setLeft(doubleLinkedNode *p)
{
    left = p;
}
void doubleLinkedNode::setRight(doubleLinkedNode *p)
{
    right = p;
}
void doubleLinkedNode::setData(void *v)
{
        data->setValue(v);
}
doubleLinkedNode::doubleLinkedNode() : data(NULL) {}
doubleLinkedNode::doubleLinkedNode(field *v) : data(v) {}
doubleLinkedNode::doubleLinkedNode(std::string *k) : data(new field(k)) {}
doubleLinkedNode::doubleLinkedNode(std::string *k, void *v) : data(new field(k, v)){};

doubleLinkedNode::~doubleLinkedNode()
{
    delete data;
}

基于双向链表节点构建双向链表

//doubleLinked.h
#pragma once
#include "doubleLinkedNode.h"
#include "observers.h"
class doubleLinked
{
private:
    /* data */
    doubleLinkedNode *head, *tail;
    unsigned int size;
    observers *observer;

public:
    doubleLinkedNode *find(std::string *key);
    bool _insert(std::string *key, void *value);
    bool _update(std::string *key, void *value);
    bool _delete(std::string *key);
    void *_select(std::string *key);
    unsigned int getSize();
    void creatObserver(observers *obs);
    doubleLinked();
    ~doubleLinked();
};
//doubleLinked.cpp
#include "doubleLinked.h"
doubleLinkedNode *doubleLinked::find(std::string *key)
{
    doubleLinkedNode *it = head->getRight();
    doubleLinkedNode *end = tail;
    while (it != end && *key != *it->getData()->getKey())
    {
        it = it->getRight();
    }
    return it;
}
bool doubleLinked::_insert(std::string *key, void *value)
{
    doubleLinkedNode *it = find(key);
    if (it == tail)
    {
        doubleLinkedNode *insertObject = new doubleLinkedNode(key, value);
        insertObject->setRight(tail);
        insertObject->setLeft(tail->getLeft());
        tail->getLeft()->setRight(insertObject);
        tail->setLeft(insertObject);
        size++;
        if(observer!=NULL)
            observer->flagAdd();
    }
    return true;
}
bool doubleLinked::_update(std::string *key, void *value)
{
    doubleLinkedNode *it = find(key);
    if (it == tail)
        return false;
    it->setData(value);
    return true;
}
bool doubleLinked::_delete(std::string *key)
{
    doubleLinkedNode *it = find(key);
    if (it != tail)
    {
        it->getLeft()->setRight(it->getRight());
        it->getRight()->setLeft(it->getLeft());
        size--;
        if(observer!=NULL)
            observer->flagSub();
        delete it;
    }
    return true;
}
void *doubleLinked::_select(std::string *key)
{
    doubleLinkedNode *it = find(key);
    if (it == tail)
        return NULL;
    return it->getData()->getValue();
}

unsigned int doubleLinked::getSize()
{
    return size;
}
void doubleLinked::creatObserver(observers *obs)
{
    observer = obs;
}
doubleLinked::doubleLinked() : head(new doubleLinkedNode()), tail(new doubleLinkedNode()), size(0)
{
    head->setRight(tail);
    tail->setLeft(head);
}
doubleLinked::~doubleLinked()
{
    doubleLinkedNode *de = head;
    doubleLinkedNode *it = head->getRight();
    while (it != tail)
    {
        delete de;
        de = it;
        it = it->getRight();
    }
    delete de;
    delete it;
}

基于双向链表实现存储的hash结构

//hashTable.h
#pragma once
#include "doubleLinked.h"
class hashTable : public dataBase
{
private:
    unsigned int tableSize;
    std::hash<std::string> strHash;
    std::hash<unsigned long> longHash;
    doubleLinked *table;

public:
    hashTable(unsigned int size);
    ~hashTable();
    unsigned int hashMapping(std::string *s);
    bool __insert__(void *key, void *value);
    bool __update__(void *key, void *value);
    bool __delete__(void *key);
    void *__select__(void *key);
    unsigned int __getSize__();
};
//hashTable.cpp
#include "hashTable.h"
hashTable::hashTable(unsigned int size) : tableSize(size), table(new doubleLinked[size])
{
    for (unsigned int i = 0; i < size; i++)
    {
        table[i].creatObserver(&counter);
    }
};
hashTable::~hashTable()
{
    delete table;
}
unsigned int hashTable::hashMapping(std::string *s)
{
    unsigned long temp = strHash(*s);
    temp = longHash(temp);
    return temp % tableSize;
}
bool hashTable::__insert__(void *k, void *value)
{
    std::string *key = static_cast<std::string *>(k);
    unsigned int hash = hashMapping(key);
    return table[hash]._insert(key, value);
}
bool hashTable::__update__(void *k, void *value)
{
    std::string *key = static_cast<std::string *>(k);
    unsigned int hash = hashMapping(key);
    return table[hash]._update(key, value);
}
bool hashTable::__delete__(void *k)
{
    std::string *key = static_cast<std::string *>(k);
    unsigned int hash = hashMapping(key);
    return table[hash]._delete(key);
}
void *hashTable::__select__(void *k)
{
    std::string *key = static_cast<std::string *>(k);
    unsigned int hash = hashMapping(key);
    return table[hash]._select(key);
}
unsigned int hashTable::__getSize__()
{
    return counter.getFlag();
}

构建所有数据对象公有的接口

//dataBase.h
#pragma once
#include <iostream>
#include "observers.h"
class dataBase
{
protected:
    observers counter;

public:
    virtual bool __insert__(void *key, void *value) = 0;
    virtual bool __update__(void *key, void *value) = 0;
    virtual bool __delete__(void *key) = 0;
    virtual void *__select__(void *key) = 0;
    virtual unsigned int __getSize__() = 0;
    virtual ~dataBase(){};
};

观察者负责记录数据库有多少个数据对象

//observers.h
#pragma once
class observers
{
private:
    int flag;

public:
    observers();
    int getFlag();
    void flagAdd();
    void flagSub();
};
//observers.cpp
#include "observers.h"
observers::observers() : flag(0) {}

int observers::getFlag()
{
    return flag;
}
void observers::flagAdd()
{
    flag++;
}
void observers::flagSub()
{
    flag--;
}

基于hash表构建数据创建工厂(方便以后扩充存储结构)

//dataBaseFactory.h
#pragma once
#include "dataBase.h"
#include "hashTable.h"
#include "repeatableHashTable.h"
#define __HASHTABLE__ 0
class dataBaseFactory
{
public:
    dataBase *createBase(short int model, unsigned int size);
};
//dataBaseFactory.cpp
#include "dataBaseFactory.h"
dataBase *dataBaseFactory::createBase(short int model, unsigned int size)
{
    switch (model)
    {
    case 0:
        return new hashTable(size);
    default:
        return NULL;
    }
}

main函数

//mian.cpp
#include "dataBaseFactory.h"
dataBaseFactory *Factory = new dataBaseFactory();
dataBase *table = Factory->createBase(__HASHTABLE__, 20);
table -> __insert__(指向字符串的指针, 指向任意数据对象的指针);
table -> __update__(指向字符串的指针, 指向任意数据对象的指针);
table -> __delete__(指向字符串的指针);
void * data = table -> __select__(指向字符串的指针);
//void指针不能直接使用需要转换成相应的数据对象指针以下用string做示例
std::string * dataStr = static_cast<std::string *>(data);
std::cout << *dataStr << std::endl;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值