用C++實現高效的哈希表

一、哈希表的介紹

哈希表是一種數據結構,通過將關鍵字映射到哈希表中的位置來實現快速查找和插入。哈希表通常具有常數時間複雜度,在實際應用中經常用於快速存儲和查找數據。

二、哈希函數的設計

哈希函數的設計是哈希表實現中非常關鍵的一步。一個好的哈希函數能使關鍵字儘可能地平均地分散在哈希表中,從而降低哈希碰撞的概率。

哈希函數的設計需要滿足以下幾點要求:

1. 哈希函數應該能夠將任意長度的輸入映射到固定大小的輸出。

2. 哈希函數應該儘可能地簡單,以提升哈希運算的速度。

3. 哈希函數應該能夠將關鍵字均勻地映射到哈希表的各個位置。

unsigned int hashFunction(const std::string& str)
{
    unsigned int hash = 5381;
    for (char c : str)
    {
        hash = ((hash << 5) + hash) + c;
    }
    return hash;
}

三、哈希衝突的解決

哈希衝突指的是兩個不同的關鍵字被哈希函數映射到同一位置的情況。解決哈希衝突的方法通常有開放定址法和鏈表法兩種。

開放定址法是指當發生哈希衝突時,從衝突的位置開始依次往下查找空閑的位置,並將元素插入到第一個空閑的位置中。

void insert(const std::string& key, const T& value)
{
    const unsigned int hash = hashFunction(key);
    unsigned int index = hash % m_tableSize;

    while (m_elements[index].first != "")
    {
        if (m_elements[index].first == key)
        {
            m_elements[index].second = value;
            return;
        }
        index = (index + 1) % m_tableSize;
    }

    m_elements[index] = std::make_pair(key, value);
    ++m_size;
}

鏈表法是指將哈希衝突的元素插入到同一個位置上的一個鏈表中。當查找哈希表中的元素時,需要依次遍歷鏈表上的每個元素。

void insert(const std::string& key, const T& value)
{
    const unsigned int hash = hashFunction(key);
    unsigned int index = hash % m_tableSize;
    for (auto& element : m_elements[index])
    {
        if (element.first == key)
        {
            element.second = value;
            return;
        }
    }
    m_elements[index].emplace_back(key, value);
    ++m_size;
}

四、哈希表的性能優化

哈希表的性能優化包括哈希函數的優化、哈希表的容量、哈希衝突的解決等。

1. 哈希函數的優化可以通過合理的設計哈希函數和鏡像哈希等技術來提高哈希表的查找效率。

2. 哈希表的容量需要合理設置,通常設置為質數能夠提高哈希表的性能。

3. 哈希衝突的解決需要選擇合適的方法來解決,不同的解決方案適用於不同的場景。

五、完整代碼示例

#include 
#include 
#include 

template 
class HashTable
{
public:
    HashTable(unsigned int tableSize)
        : m_tableSize(tableSize)
        , m_size(0)
        , m_elements(tableSize)
    {}

    void insert(const std::string& key, const T& value)
    {
        const unsigned int hash = hashFunction(key);
        unsigned int index = hash % m_tableSize;
        for (auto& element : m_elements[index])
        {
            if (element.first == key)
            {
                element.second = value;
                return;
            }
        }
        m_elements[index].emplace_back(key, value);
        ++m_size;
    }

    bool get(const std::string& key, T& value) const
    {
        const unsigned int hash = hashFunction(key);
        const unsigned int index = hash % m_tableSize;
        for (const auto& element : m_elements[index])
        {
            if (element.first == key)
            {
                value = element.second;
                return true;
            }
        }
        return false;
    }

    bool remove(const std::string& key)
    {
        const unsigned int hash = hashFunction(key);
        const unsigned int index = hash % m_tableSize;
        auto& chain = m_elements[index];
        for (auto it = chain.begin(); it != chain.end(); ++it)
        {
            if (it->first == key)
            {
                chain.erase(it);
                --m_size;
                return true;
            }
        }
        return false;
    }

    unsigned int size() const
    {
        return m_size;
    }

private:
    std::vector<std::vector<std::pair>> m_elements;
    const unsigned int m_tableSize;
    unsigned int m_size;

    unsigned int hashFunction(const std::string& str) const
    {
        unsigned int hash = 5381;
        for (char c : str)
        {
            hash = ((hash << 5) + hash) + c;
        }
        return hash;
    }
};

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/153050.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-13 06:08
下一篇 2024-11-13 06:08

相關推薦

  • Trocket:打造高效可靠的遠程控制工具

    如何使用trocket打造高效可靠的遠程控制工具?本文將從以下幾個方面進行詳細的闡述。 一、安裝和使用trocket trocket是一個基於Python實現的遠程控制工具,使用時…

    編程 2025-04-28
  • Python生成列表最高效的方法

    本文主要介紹在Python中生成列表最高效的方法,涉及到列表生成式、range函數、map函數以及ITertools模塊等多種方法。 一、列表生成式 列表生成式是Python中最常…

    編程 2025-04-28
  • TFN MR56:高效可靠的網路環境管理工具

    本文將從多個方面深入闡述TFN MR56的作用、特點、使用方法以及優點,為讀者全面介紹這一高效可靠的網路環境管理工具。 一、簡介 TFN MR56是一款多功能的網路環境管理工具,可…

    編程 2025-04-27
  • 用Pythonic的方式編寫高效代碼

    Pythonic是一種編程哲學,它強調Python編程風格的簡單、清晰、優雅和明確。Python應該描述為一種語言而不是一種編程語言。Pythonic的編程方式不僅可以使我們在編碼…

    編程 2025-04-27
  • Python生成10萬條數據的高效方法

    本文將從以下幾個方面探討如何高效地生成Python中的10萬條數據: 一、使用Python內置函數生成數據 Python提供了許多內置函數可以用來生成數據,例如range()函數可…

    編程 2025-04-27
  • Gino FastAPI實現高效低耗ORM

    本文將從以下多個方面詳細闡述Gino FastAPI的優點與使用,展現其實現高效低耗ORM的能力。 一、快速入門 首先,我們需要在項目中安裝Gino FastAPI: pip in…

    編程 2025-04-27
  • 如何利用位元組跳動推廣渠道高效推廣產品

    對於企業或者個人而言,推廣產品或者服務是必須的。如何讓更多的人知道、認識、使用你的產品是推廣的核心問題。而今天,我們要為大家介紹的是如何利用位元組跳動推廣渠道高效推廣產品。 一、個性…

    編程 2025-04-27
  • 如何製作高效的目標識別數據集

    對於機器學習中的目標識別任務來說,製作高質量的數據集對於訓練模型十分重要。本文將從數據收集、數據標註、數據增強等方面闡述如何製作高效的目標識別數據集。 一、數據收集 在製作目標識別…

    編程 2025-04-27
  • 用mdjs打造高效可復用的Web組件

    本文介紹了一個全能的編程開發工程師如何使用mdjs來打造高效可復用的Web組件。我們將會從多個方面對mdjs做詳細的闡述,讓您輕鬆學習並掌握mdjs的使用。 一、mdjs簡介 md…

    編程 2025-04-27
  • 如何設計一個高效的中台產品

    本文介紹中台產品的設計思路,並從用戶、技術和可維護性等多個方面進行詳細闡述。 一、用戶體驗至上 中台產品的首要目標是滿足用戶需求和提升用戶體驗。因此,中台產品的設計應該以用戶為中心…

    編程 2025-04-27

發表回復

登錄後才能評論