如何在此哈希图中实现AVL树?

时间:2019-06-04 21:04:57

标签: c++ templates generics hashmap avl-tree

所以我的朋友挑战我尝试创建一个使用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应该可以与哈希映射一起正常工作,但是我不确定如何将两者隐喻地联系起来。

1 个答案:

答案 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
   }

...