所以我的朋友挑战我尝试创建一个使用AVL树而非存储桶来存储多个节点的哈希映射。根据老师的建议,我创建了一个标准的哈希图作为起点,但是我不确定从这里要去哪里。任何帮助将不胜感激! :)
我首先用数组制作了一个平常的书,以便能够更好地理解我的作品,但是我不能确定该从何而来。我尝试简单地将数组复制粘贴到AVL处,但这只会导致大量未定义的行为。
Node.h
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <float.h>
#include <iostream>
template<typename K, typename V>
//Hashnode class
class HashNode
{
public:
V value;
HashNode* left;
HashNode* right;
K key;
//Constructor of hashnode
HashNode(K key, V value)
{
this->value = value;
this->key = key;
}
};
_________________________________________________________________
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <float.h>
#include <iostream>
#include "Node.h"
using namespace std;
//template for generic type
template<typename K, typename V>
//Our own Hashmap class
class HashMap
{
//hash element array
HashNode<K, V> **arr;
int capacity;
//current size
int size;
//dummy node
HashNode<K, V> *dummy;
public:
HashMap()
{
//Initial capacity of hash array
capacity = 20;
size = 0;
arr = new HashNode<K, V>*[capacity];
//Initialise all elements of array as NULL
for (int i = 0; i < capacity; i++)
arr[i] = NULL;
//dummy node with value and key -1
dummy = new HashNode<K, V>(-1, -1);
}
// This implements hash function to find index
// for a key
int hashCode(K key)
{
return key % capacity;
}
//Function to add key value pair
void insertNode(K key, V value)
{
HashNode<K, V> *temp = new HashNode<K, V>(key, value);
// Apply hash function to find index for given key
int hashIndex = hashCode(key);
//find next free space
while (arr[hashIndex] != NULL && arr[hashIndex]->key != key
&& arr[hashIndex]->key != -1)
{
hashIndex++;
hashIndex %= capacity;
}
//if new node to be inserted increase the current size
if (arr[hashIndex] == NULL || arr[hashIndex]->key == -1)
size++;
arr[hashIndex] = temp;
}
//Function to delete a key value pair
V deleteNode(int key)
{
// Apply hash function to find index for given key
int hashIndex = hashCode(key);
//finding the node with given key
while (arr[hashIndex] != NULL)
{
//if node found
if (arr[hashIndex]->key == key)
{
HashNode<K, V> *temp = arr[hashIndex];
//Insert dummy node here for further use
arr[hashIndex] = dummy;
// Reduce size
size--;
return temp->value;
}
hashIndex++;
hashIndex %= capacity;
}
//If not found return null
return NULL;
}
//Function to search the value for a given key
V get(int key)
{
// Apply hash function to find index for given key
int hashIndex = hashCode(key);
int counter = 0;
//finding the node with given key
while (arr[hashIndex] != NULL)
{
int counter = 0;
if (counter++ > capacity) //to avoid infinite loop
return NULL;
//if node found return its value
if (arr[hashIndex]->key == key)
return arr[hashIndex]->value;
hashIndex++;
hashIndex %= capacity;
}
//If not found return null
return NULL;
}
//Return current size
int sizeofMap()
{
return size;
}
//Return true if size is 0
bool isEmpty()
{
return size == 0;
}
//Function to display the stored key value pairs
void display()
{
for (int i = 0; i < capacity; i++)
{
if (arr[i] != NULL && arr[i]->key != -1)
cout << "key = " << arr[i]->key
<< " value = " << arr[i]->value << endl;
}
}
};
预期结果是AVL应该可以与哈希映射一起正常工作,但是我不确定如何将两者隐喻地联系起来。
答案 0 :(得分:0)
您当前的实现使用了在发生哈希冲突的情况下查找另一个空闲节点的策略。如果要使用AVL(或R / B)树,则应扩展每个数组元素以存储所有冲突。第一步,您可以在每个节点中保留一个链接列表或指向矢量的指针。下一步是使用树库。最好是内置的。通常std :: map使用红黑树,它与AVL同构,但性能概况略有不同。您可以将std映射用作“树”容器。
请注意,您的密钥类型必须具有可比性(运算符 << / strong>,并且还应提供一种计算哈希值的方法。您当前的实现意味着基数类型可转换到整数。
template<typename K, typename V>
class HashMap
{
typedef stf::map HashNode;
...
void insertNode(K key, V value)
{
HashNode<K, V> *temp = new HashNode<K, V>={{key, value}};
// Apply hash function to find index for given key
int hashIndex = hashCode(key);
if(NULL == arr[hashIndex] ){
arr[hashIndex] = new std::map<K,V>();
}
arr[hashIndex]->insert(std::pair<K,V>(key,value);
size++;
...
//resize if the capacity is needed
}
...