• hash 表 --- 链地址法解决冲突


    一般在ACM比赛中,将hash表的大小设置的比较大, 如下hash表仅为了测试方便,
    故意将SIZE,M设置的比较小。

    顺序存储

    hashtable.h

    #include
    #include

    struct Node 
    {
        Node(): next(0), key(0), value() {}
        Node(int n, int k, int v)
            : next(n), key(k), value(v) {}

        int next;
        int value;
        int key;
    };

    class HashTable 
    {
    public:
        HashTable();
        ~HashTable();
        int hash(int key);
        int search(int key);
        int insert(int key, int value);
        bool modify(int key, int value);
        void show();

    private:
        //const int SIZE = 1000000;
        //const int M = 999997;
        static const int SIZE;
        static const int M;
        Node *ht;
        int *head;
        int size;
    };

    const int HashTable::SIZE = 100;
    const int HashTable::M = 3;

    HashTable::HashTable()
    {
        ht = new Node[SIZE];
        memset(ht, 0, sizeof(Node)*SIZE);
        head = new int[M];
        memset(head, 0, sizeof(int)*M);
        size = 0;
    }

    HashTable::~HashTable()
    {
        if (ht != nullptr)
            delete[] ht;
        if (head != nullptr)
            delete[] head;
    }

    int HashTable::hash(int key)
    {
        return key % M;
    }

    int HashTable::search(int key) 
    {
        for (int i = head[hash(key)]; i > 0; i = ht[i].next)
            if (ht[i].key == key)
                return ht[i].value;

        return -1;
    }

    int HashTable::insert(int key, int value)
    {
        if (search(key) != -1) 
            return -1;

        ht[++size] = Node(head[hash(key)], value, key);
        head[hash(key)] = size;

        return value;
    }

    bool HashTable::modify(int key, int value)
    {
        for (int i = head[hash(key)]; i > 0; i = ht[i].next)
            if (ht[i].key == key)
            {
                ht[i].value = value;
                return true;
            }

        return false;
    }

    void HashTable::show()
    {
        for (int i = 0; i < M; ++i)
        {
            if (head[i] > 0)
            {
                std::cout << i << " : ";
                int index = head[i];
                while (index > 0)
                {
                    std::cout << ht[index].value;
                    index = ht[index].next;
                    if (index > 0)
                        std::cout << "--> ";
                }
                std::cout << std::endl;
            }
            else
                std::cout << i << " : " << "null ..." << std::endl;
        }
    }

    main.cpp

    #include "stdafx.h"
    #include "hashtable.h"

    int _tmain(int argc, _TCHAR* argv[])
    {
        HashTable ht;
        int i = 1;
        for (; i < 8; ++i)
            ht.insert(i, i);

        std::cout << "show hash table" << std::endl;
        ht.show();

        return 0;
    }

    show hash table
    0 : 6--> 3
    1 : 7--> 4--> 1
    2 : 5--> 2

    链式存储
    HashTable2.h
    #pragma once

    #include

    struct Node
    {
        Node() :  key(0), next(nullptr) {}
        Node(int k) : key(k), next(nullptr) {}

        struct Node *next;
        int key;
    };

    class HashTable
    {
    public:
        HashTable();
        ~HashTable();
        int hash(int key);
        Node* search(int key);
        int insert(int key);
        bool remove(int key);
        void show();

    private:
        static const int SIZE;
        static const int M;
        Node** ht;
        int size;
    };

    const int HashTable::SIZE = 13;
    const int HashTable::M = 13;

    HashTable::HashTable()
    {
        ht = new Node*[SIZE];
        for (int i = 0; i < SIZE; ++i)
            ht[i] = nullptr;
    }

    HashTable::~HashTable()
    {
        if (ht != nullptr)
        {
            for (int i = 0; i < SIZE; ++i)
                if (ht[i] != nullptr)
                {
                    delete ht[i];
                    ht[i] = nullptr;
                }

            delete[] ht;
            ht = nullptr;
        }
    }

    int HashTable::hash(int key)
    {
        return key % M;
    }

    int HashTable::insert(int key)
    {
        int index = hash(key);
        Node* p = new Node(key);
        if (nullptr == p)
            return -1;
        
        p->next = ht[index];
        ht[index] = p;

        return 0;
    }

    Node* HashTable::search(int key)
    {
        int index = hash(key);
        Node* p = ht[index];
        while (p != nullptr && p->key != key)
            p = p->next;

        return p;
    }

    bool HashTable::remove(int key)
    {
        Node* p = search(key);
        if (p == nullptr)
            return false;

        int index = hash(key);
        // find precursor node of p
        Node* q = ht[index];
        while (q->next != p)
            q = q->next;

        q->next = p->next;

        delete p;
        p = nullptr;

        return true;
    }

    void HashTable::show()
    {
        for (int i = 0; i < SIZE; ++i)
        {
            std::cout << i << " : ";
            Node* p = ht[i];
            if (p != nullptr)
            {
                while (p != nullptr)
                {
                    std::cout << p->key;
                    if (p->next != nullptr)
                        std::cout << " --> ";
                    p = p->next;
                }
                std::cout << std::endl;
            }
            else
                std::cout << "Null..." << std::endl;
        }
    }

    main.cpp

    #include "stdafx.h"
    #include "HashTable2.h"

    int main()
    {
        HashTable ht;
        int arr[] = {19, 14, 23, 1, 68, 20, 84, 27, 55, 11, 10, 79};
        for (int i = 0; i < sizeof(arr) / sizeof(int); ++i)
            ht.insert(arr[i]);
        ht.show();
        std::cout << "After delete 1" << std::endl;
        ht.remove(1);
        ht.show();

        return 0;
    }

    0 : Null...
    1 : 79 --> 27 --> 1 --> 14
    2 : Null...
    3 : 55 --> 68
    4 : Null...
    5 : Null...
    6 : 84 --> 19
    7 : 20
    8 : Null...
    9 : Null...
    10 : 10 --> 23
    11 : 11
    12 : Null...
    After delete 1
    0 : Null...
    1 : 79 --> 27 --> 14
    2 : Null...
    3 : 55 --> 68
    4 : Null...
    5 : Null...
    6 : 84 --> 19
    7 : 20
    8 : Null...
    9 : Null...
    10 : 10 --> 23
    11 : 11
    12 : Null...


     

  • 相关阅读:
    嵌入式软件工程师面试题——2025校招专题(三)
    R语言使用dplyr包的arrange函数对dataframe进行排序:使用单个数据列排序、多个数据列排序、字段前添加负号进行降序排序
    Gerver view软件使用
    Web服务器实战
    医疗IT系统安科瑞隔离电源装置在医院的应用
    简单的权限验证
    leetcode: 122. 买卖股票的最佳时机II
    MATLAB画图分辨率、图像大小研究
    使用容器快速在阿里云 ECS 多节点上搭建 Citus 12.1 集群
    Arrays.asList的“坑”
  • 原文地址:https://blog.csdn.net/cai0612123/article/details/126269682