手撸Hash表实现 key-value 的插入查询删除遍历
huaru科技笔试做到用伪代码手写map的实现,可以选择使用hash表和红黑树,一个大嘴巴子。。。
Hash表
没有冲突情况
- 直接使用vector
- 除留取余
//散列函数 + 除留取余法 + 链式地址法
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
using namespace std;
template<class K, class V>
class Hash{
public:
struct Node{
K key;
V val;
Node* next;
Node(const K& _key = K(),const V& _val = V()):key(_key),val(_val),next(nullptr){}
//Node(const K& _key,const V& _val):key(_key),val(_val),next(nullptr){}
};
//static const int capacity = 101;//表的大小,不够扩容
int currentsize;
vector<Node> hashtable;
public:
int hashFunction(const K& key) const{
int sum = 0;
int index;
for (size_t i = 0; i < key.size(); ++i)
{
sum += static_cast<int>(key[i]);
}
index = sum % hashtable.size(); //除留取余
/*
cout << "key[0] = " << key[0] << endl;
cout << "key[0] = " << static_cast<int>(key[0]) << endl;
cout << "key[1] = " << key[1] << endl;
cout << "key[2] = " << key[2] << endl;
cout << "sum = " << sum << endl;
cout << "index = " << index << endl << endl;
*/
return index;
}
Hash(int _capacity = 101) :hashtable(_capacity), currentsize(0) {}
~Hash(){}
void insert(const K& key, const V& val) {
int hashcode = hashFunction(key);
hashtable[hashcode] = Node(key, val);
++currentsize;
}
V query(const K& key) const
{
int hashcode = hashFunction(key);
if (hashtable[hashcode].key == key) {
return hashtable[hashcode].val;
}
else {
return V();
}
}
void erase(const K& key) {
int hashcode = hashFunction(key);
if (hashtable[hashcode].key != K()) {
cout << "delete Node " << hashtable[hashcode].key << ":" << hashtable[hashcode].val << endl;
hashtable[hashcode] = Node();
}
else {
cout << "delete Nothing. "<<endl;
}
}
void printtable() {
for (size_t i = 0; i < hashtable.size(); i++) {
if (hashtable[i].key != K()) {
cout << hashtable[i].key << ": " << hashtable[i].val << endl;
}
}
}
};
int main(){
// 创建一个 HashMap 并开辟内存
Hash<string, int>* hm =new Hash<string, int>();
hm->insert("hua1", 1);
hm->insert("hua2", 2);
hm->insert("hua3", 3);
hm->insert("hua4", 4);
hm->insert("hua5", 5);
cout << hm->query("hua1") << endl;
cout << hm->query("hua2") << endl;
cout << hm->query("hua3") << endl;
cout << hm->query("hua4") << endl;
cout << hm->query("hua5") << endl;
hm->printtable();
hm->erase("hua4");
hm->printtable();
delete hm;
return 0;
}
存在冲突
- vector
- 除留取余
- 桶(拉链法)
没写完,erase和遍历没写
没写迭代器
有待改进,先酱汁
//散列函数 + 除留取余法 + 链式地址法
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
using namespace std;
template<class K, class V>
class Hash {
public:
struct Node {
K key;
V val;
Node* next;
Node(const K& _key = K(), const V& _val = V()) :key(_key), val(_val), next(nullptr) {}
Node(const K& _key,const V& _val,Node * _next):key(_key),val(_val),next(_next){}
};
//static const int capacity = 101;//表的大小,不够扩容
int currentsize;
vector<Node*> hashtable;
public:
int hashFunction(const K& key) const {
int sum = 0;
int index;
for (size_t i = 0; i < key.size(); ++i)
{
sum += static_cast<int>(key[i]);
}
index = sum % hashtable.size(); //除留取余
/*
cout << "key[0] = " << key[0] << endl;
cout << "key[0] = " << static_cast<int>(key[0]) << endl;
cout << "key[1] = " << key[1] << endl;
cout << "key[2] = " << key[2] << endl;
cout << "sum = " << sum << endl;
cout << "index = " << index << endl << endl;
*/
return index;
}
Hash(int _capacity = 101) :hashtable(_capacity), currentsize(0) {
for (int i = 0; i < _capacity; i++) {
hashtable[i] = nullptr;
}
}
~Hash() {}
void insert(const K& key, const V& val) {
int hashcode = hashFunction(key);
if (hashtable[hashcode] == nullptr) {
hashtable[hashcode] = new Node(key, val);
++currentsize;
return;
}
Node* p = hashtable[hashcode];
while (p->next != nullptr) {
//如果key相同,就要覆盖
if (key == p->key && hashFunction(key) == hashFunction(p->key)) {
p->val = val;
return;
}
p = p->next;
}
Node *tmp = new Node(key, val, hashtable[hashcode]);
hashtable[hashcode] = tmp;
++currentsize;
return;
}
V query(const K& key) const
{
int hashcode = hashFunction(key);
if (hashtable[hashcode] == nullptr) return V();
Node* p = hashtable[hashcode];
while (p!=nullptr) {
if (key == p->key && hashFunction(key) == hashFunction(p->key)) {
return p->val;
}
p = p->next;
}
return V();
}
void erase(const K& key) {
int hashcode = hashFunction(key);
if (hashtable[hashcode].key != K()) {
cout << "delete Node " << hashtable[hashcode].key << ":" << hashtable[hashcode].val << endl;
hashtable[hashcode] = Node();
}
else {
cout << "delete Nothing. " << endl;
}
}
};
int main() {
// 创建一个 HashMap 并开辟内存
Hash<string, int>* hm = new Hash<string, int>();
hm->insert("hua1", 1);
hm->insert("hua2", 2);
hm->insert("hua3", 3);
hm->insert("hua4", 4);
hm->insert("hua5", 5);
cout << hm->query("hua1") << endl;
cout << hm->query("hua2") << endl;
cout << hm->query("hua3") << endl;
cout << hm->query("hua4") << endl;
cout << hm->query("hua5") << endl;
delete hm;
return 0;
}
在面试老师的指点下,告诉我用指针数组来写,于是乎,先贴一个demo
#include<iostream>
#include<string>
#incldue<vector>
using namespace std;
template<class K,class V>
class Hash{
public:
struct Node{
K key;
V val;
Node* next;
Node(const K& _key = K(),const V& _val = V()):key(_key),val(_val),next(nullptr){}
};
int currentsize;
vector<Node*> hashtable;
int hashfunc(const &key){
}
Hash(int size = 100):currentsize(0),hashtable(size){
for(int i=0;i<size;++i){
hashtable[i]=nullptr;
}
}
~Hash(){}
void insert(K &key,V &val){
int hashcode = hashfunc(key)
if(hashtable[hashcode]==nullptr){
Node * tmp = new Node(key,val);
hashtable[hashcode]= tmp;
}else{
Node* cur = hashtable[hashcode];
while(cur->next!=nullptr){
cur = cur->next;
}
Node *tmp = new Node(key,val);
cur->next = tmp;
}
}
};