Untitled

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
21 kB
1
Indexable
Never
//! linear probing
{

#include <bits/stdc++.h>
    using namespace std;

    // template for generic type
    template <typename K, typename V>

    // Hashnode class
    class HashNode
    {
    public:
        V value;
        K key;

        // Constructor of hashnode
        HashNode(K key, V value)
        {
            this->value = value;
            this->key = key;
        }
    };

    // 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
            //! 如果位置已經有人,且不是重複的key
            while (arr[hashIndex] != NULL && arr[hashIndex]->key != key && arr[hashIndex]->key != -1)
            // while (arr[hashIndex] != NULL && arr[hashIndex]->key != key)
            {
                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; // BUG!

                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;
            }
        }
    };

    // Driver method to test map class
    int main()
    {
        HashMap<int, int> *h = new HashMap<int, int>;
        h->insertNode(1, 1);
        h->insertNode(2, 2);
        h->insertNode(2, 3);
        h->insertNode(1, 3);
        h->insertNode(1, 4);
        h->insertNode(3, 4);
        h->insertNode(7, 4);
        h->insertNode(8, 3);
        h->display();
        cout << h->sizeofMap() << endl;
        cout << h->deleteNode(2) << endl;
        cout << h->sizeofMap() << endl;
        cout << h->isEmpty() << endl;
        cout << h->get(2);

        return 0;
    }
}
//!  quadratic probing-1
{
    // C++ code
#include <iostream>
#include <string>

    using std::cout;
    using std::endl;
    using std::string;

    struct dict
    {
        int key;
        string value;
        dict() : key(0), value(""){};
        dict(int k, string s) : key(k), value(s){};
    };

    class HashOpenAddress
    {
    private:
        int size, count;
        dict *table;

        int QuadraticProbing(int key, int i);

        // TableDoubling()
        // TableShrinking()
        // Rehashing()

    public:
        HashOpenAddress() : size(0), count(0), table(0){};
        HashOpenAddress(int m) : size(m), count(0)
        {
            table = new dict[size];
        }
        void Insert(int key, string value);
        void Delete(int key);
        string Search(int key);
        void Display();
    };

    string HashOpenAddress::Search(int key)
    {

        int i = 0;
        while (i != size)
        {
            int j = QuadraticProbing(key, i);
            if (table[j].key == key)
            {
                return table[j].value;
            }
            else
            {
                i++;
            }
        }
        return "...data not found\n";
    }

    void HashOpenAddress::Delete(int key)
    {

        int i = 0;
        while (i != size)
        {
            int j = QuadraticProbing(key, i);
            if (table[j].key == key)
            {
                table[j].key = 0;
                table[j].value = "";
                count--;
                return;
            }
            else
            {
                i++;
            }
        }
        cout << "...data not found\n";
    }

    void HashOpenAddress::Insert(int key, string value)
    {

        int i = 0;
        while (i != size)
        {
            int j = QuadraticProbing(key, i);
            if (table[j].value == "")
            {
                table[j].key = key;
                table[j].value = value;
                count++;
                return;
            }
            else
            {
                i++;
            }
        }
        cout << "Hash Table Overflow\n";
    }

    int HashOpenAddress::QuadraticProbing(int key, int i)
    {
        // c1 = c2 = 0.5
        return ((int)((key % size) + 0.5 * i + 0.5 * i * i) % size);
    }

    void HashOpenAddress::Display()
    {

        for (int i = 0; i < size; i++)
        {
            cout << "slot#" << i << ": (" << table[i].key
                 << "," << table[i].value << ")" << endl;
        }
        cout << endl;
    }
    int main()
    {

        HashOpenAddress hash(8);   // probing sequence:
        hash.Insert(33, "blue");   // 1,2,4,7,3,0,6,5 -> 1
        hash.Insert(10, "yellow"); // 2,3,5,0,4,1,7,6 -> 2
        hash.Insert(77, "red");    // 5,6,0,3,7,4,2,1 -> 5
        hash.Insert(2, "white");   // 2,3,5,0,4,1,7,6 -> 3
        hash.Display();
        hash.Insert(8, "black");       // 0,1,3,6,2,7,5,4 -> 0
        hash.Insert(47, "gray");       // 7,0,2,5,1,6,4,3 -> 7
        hash.Insert(90, "purple");     // 2,3,5,0,4,1,7,6 -> 4
        hash.Insert(1, "deep purple"); // 4,5,7,2,6,3,1,0 -> 6
        hash.Display();
        hash.Insert(15, "green"); // hash table overflow

        cout << "number#90 is " << hash.Search(90) << "\n\n";

        hash.Delete(90);
        cout << "after deleting (90,purple):\n";
        cout << "number#90 is " << hash.Search(90) << "\n";

        hash.Insert(12, "orange"); // 4,5,7,2,6,3,1,0 -> 4
        hash.Display();

        return 0;
    }
}
//! quardetic probing-2
{

// C++ implementation of
// the Quadratic Probing
#include <bits/stdc++.h>
    using namespace std;

    // Function to print an array
    void printArray(int arr[], int n)
    {
        // Iterating and printing the array
        for (int i = 0; i < n; i++)
        {
            cout << arr[i] << " ";
        }
    }

    // Function to implement the
    // quadratic probing
    void hashing(int table[], int tsize, int arr[], int N)
    {
        // Iterating through the array
        for (int i = 0; i < N; i++)
        {
            // Computing the hash value
            int hv = arr[i] % tsize;

            // Insert in the table if there
            // is no collision
            if (table[hv] == -1)
                table[hv] = arr[i];
            else
            {
                // If there is a collision
                // iterating through all
                // possible quadratic values
                for (int j = 0; j < tsize; j++)
                {
                    // Computing the new hash value
                    int t = (hv + j * j) % tsize;
                    if (table[t] == -1)
                    {
                        // Break the loop after
                        // inserting the value
                        // in the table
                        table[t] = arr[i];
                        break;
                    }
                }
            }
        }
        printArray(table, N);
    }

    // Driver code
    int main()
    {
        int arr[] = {50, 700, 76, 85, 92, 73, 101};
        int N = 7;

        // Size of the hash table
        int L = 7;
        int hash_table[7];

        // Initializing the hash table
        for (int i = 0; i < L; i++)
        {
            hash_table[i] = -1;
        }

        // Function call
        hashing(hash_table, L, arr, N);
        return 0;
    }

    // This code is contributed by gauravrajput1
}

//! chaining
{
// C++ code
#include <iostream>
#include <vector>
#include <string>
#include <math.h> // floor()

    using std::cout;
    using std::endl;
    using std::string;
    using std::vector;

    struct Node
    {
        int key;      // number
        string value; // genre
        Node *next;   // pointer to remember memory address of next node

        Node() : key(0), value(""), next(0){};
        Node(int Key, string Value) : key(Key), value(Value), next(0){};
        Node(Node const &data) : key(data.key), value(data.value), next(data.next){};
    };

    class HashChainNode
    {
    private:
        int size,     // size: size of table, count: number of data
            count;    // count/size = load factor
        Node **table; // pointer to pointer, hash table

        int HashFunction(int key); // Multiplication method
        void TableDoubling();
        void TableShrinking();
        void Rehashing(int size_orig);

    public:
        HashChainNode(){};
        HashChainNode(int m) : size(m), count(0)
        {
            table = new Node *[size]; // allocate the first demension of table
            for (int i = 0; i < size; i++)
            {                 // initialization
                table[i] = 0; // ensure every slot points to NULL
            }
        }
        ~HashChainNode();

        void Insert(Node data); // consider TableDoubling()
        void Delete(int key);   // consider TableShrinking()
        string Search(int key);
        void DisplayTable();
    };

    void HashChainNode::Insert(Node data)
    {

        count++;
        if (count > size)
        {                    // consider load factor
            TableDoubling(); // if n/m > 1, then double the size of table
        }

        int index = HashFunction(data.key); // get index of slot
        Node *newNode = new Node(data);     // create new node to store data

        // push_front()
        if (table[index] == NULL)
        {                           // eg: list: (empty), add4
            table[index] = newNode; // eg: list: 4->NULL
        }
        else
        {                                    // eg: list: 5->9->NULL  , add 4
            Node *next = table[index]->next; //     list: 5->4->9->NULL
            table[index]->next = newNode;
            newNode->next = next;
        }
    }

    void HashChainNode::Delete(int key)
    {

        int index = HashFunction(key); // get index of slot
        Node *current = table[index],  // use two pointer for traversal in list
            *previous = NULL;

        while (current != NULL && current->key != key)
        {
            previous = current;      // traversal in list, 3 cases:
            current = current->next; // 1. data not found
        }                            // 2. data found at first node in list
                                     // 3. data found at other position in list

        if (current == NULL)
        { // eg: list:5->2->9->NULL, want to delete 3
            cout << "data not found.\n\n";
            return;
        }
        else
        {
            if (previous == NULL)
            {                                 // eg: list:5->2->9->NULL, want to delete 5
                table[index] = current->next; // after deleting 5, list:2->9->NULL
            }                                 // current points to 5

            else
            {                                   // eg: list:5->2->9->NULL, want to delete 2
                previous->next = current->next; // after deleting 2, list:5->9->NULL
            }                                   // current points to 2
            delete current;
            current = 0;
        }

        count--;
        if (count < size / 4)
        {                     // consider load factor
            TableShrinking(); // if n/m < 4, then shrink the table
        }
    }

    string HashChainNode::Search(int key)
    {

        int index = HashFunction(key); // get index of slot
        Node *current = table[index];  // current points to the first node in list

        while (current != NULL)
        { // traversal in list
            if (current->key == key)
            {
                return current->value;
            }
            current = current->next;
        }
        return "...\nno such data";
    }

    int HashChainNode::HashFunction(int key)
    {
        // Multiplication method
        double A = 0.6180339887,
               frac = key * A - floor(key * A);
        return floor(this->size * frac);
    }

    void HashChainNode::TableDoubling()
    {

        int size_orig = size; // size_orig represents the original size of table
        size *= 2;            // double the size of table
        Rehashing(size_orig);
        ; // create new table with new larger size
    }

    void HashChainNode::TableShrinking()
    {

        int size_orig = size; // size_orig represents the original size of table
        size /= 2;            // shrink the size of table
        Rehashing(size_orig); // create new table with new smaller size
    }

    void HashChainNode::Rehashing(int size_orig)
    {

        Node **newtable = new Node *[size]; // allocate memory for new table
        for (int i = 0; i < size; i++)
        {                    // initializetion
            newtable[i] = 0; // ensure every node in slot points to NULL
        }

        for (int i = 0; i < size_orig; i++)
        { // visit every node in the original table

            Node *curr_orig = table[i], // curr_orig: current node in original table
                *prev_orig = NULL;      // prev_orig: following curr_orig

            while (curr_orig != NULL)
            { // traversal in list of each slot in original table

                prev_orig = curr_orig->next; // curr_orig will be directly move to new table
                                             // need prev_orig to keep pointer in original table

                int index = HashFunction(curr_orig->key); // get index of slot in new table

                // push_front(), do not allocate new memory space for data
                // directly move node in original table to new table
                if (newtable[index] == NULL)
                { // means newtable[index] is empty
                    newtable[index] = curr_orig;
                    newtable[index]->next = 0; // equivalent to curr_orig->next = 0;
                }
                // if there is no initialization for newtable, segmentation faults might happen
                // because newtable[index] might not point to NULL
                // but newtable[index] is empty
                else
                {                                       // if newtable[index] is not empty
                    Node *next = newtable[index]->next; // push_front()
                    newtable[index]->next = curr_orig;
                    curr_orig->next = next;
                }
                curr_orig = prev_orig; // visit the next node in list in original table
            }
        }
        delete[] table;         // release memory of original table
        this->table = newtable; // point table of object to new table
    }

    HashChainNode::~HashChainNode()
    {

        for (int i = 0; i < size; i++)
        {                             // visit every node in table
                                      // and release the memory of each node
            Node *current = table[i]; // point *current to first node in list
            while (current != NULL)
            { // traversal in list
                Node *previous = current;
                current = current->next;
                delete previous;
                previous = 0;
            }
        }
        delete[] table;
    }

    void HashChainNode::DisplayTable()
    {

        for (int i = 0; i < size; i++)
        { // visit every node in table
            cout << "#slot#" << i << ": ";
            Node *current = table[i];
            while (current != NULL)
            {
                cout << "(" << current->key << "," << current->value << ") ";
                current = current->next;
            }
            cout << endl;
        }
        cout << endl;
    }

    int main()
    {

        HashChainNode hash(2);

        hash.Insert(Node(12, "post rock"));
        hash.Insert(Node(592, "shoegaze"));
        cout << "After inserting key(12),key(592):\n";
        hash.DisplayTable();
        hash.Insert(Node(6594, "blues")); // evoke TableDoubling()
        cout << "After inserting key(6594), evoke TableDoubling():\n";
        hash.DisplayTable();
        hash.Insert(Node(7, "folk"));
        cout << "After inserting key(7):\n";
        hash.DisplayTable();
        hash.Insert(Node(123596, "hiphop")); // evoke TableDoubling()
        cout << "After inserting key(123596), evoke TableDoubling():\n";
        hash.DisplayTable();
        hash.Insert(Node(93, "soul"));
        hash.Insert(Node(2288, "indie"));
        hash.Insert(Node(793, "jazz"));
        cout << "After inserting key(93),key(2288),key(793):\n";
        hash.DisplayTable();
        hash.Insert(Node(8491, "electro")); // evoke TableDoubling()
        cout << "After inserting key(8491), evoke TableDoubling():\n";
        hash.DisplayTable();
        hash.Insert(Node(323359, "pop"));
        cout << "After inserting key(323359):\n";
        hash.DisplayTable();

        cout << "Searching: genre(8491) is " << hash.Search(8491) << ".\n\n";
        cout << "Searching: genre(7) is " << hash.Search(7) << ".\n\n";

        hash.Delete(7);
        cout << "After deleting key(7):\n";
        cout << "Searching: genre(7) is " << hash.Search(7) << ".\n\n";

        hash.Delete(592);
        cout << "After deleting key(592):\n";
        hash.DisplayTable();

        cout << "Want to  delete key(592) again:\n";
        hash.Delete(592);

        hash.Delete(123596);
        hash.Delete(323359);
        hash.Delete(793);
        hash.Delete(93);
        cout << "After deleting key(123596),key(323359),key(793),key(93):\n";
        hash.DisplayTable();

        hash.Delete(6594); // evoke TableShrinking()
        cout << "After deleting key(6594), evoke TableShrinking():\n";
        hash.DisplayTable();

        return 0;
    }
}