溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java數據結構中哈希表的線性探測算法是什么

發布時間:2021-12-27 17:13:34 來源:億速云 閱讀:134 作者:柒染 欄目:編程語言

本篇文章給大家分享的是有關java數據結構中哈希表的線性探測算法是什么,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

構造哈希表常用的方法是:

除留余數法--取關鍵值被某個不大于散列表長m的數p除后的所得的余數為散列地址。HashKey= Key % P。

直接定址法--取關鍵字的某個線性函數為散列地址HashKey= Key 或 HashKey= A*Key + BA、B為常數。

我在這里主要使用一下除留余數法Hash(key) =Key%P,(P這里是哈希表的長度)p最好是素數考慮降低哈希沖突的原因,我并沒有在這上面過于追究此處哈希表長度10,見線性探測圖。

哈希表經常遇到的一個問題就是哈希沖突。

哈希沖突是什么呢?哈希沖突指的是:不同的關鍵字經過相同的哈希函數映射到相同的的哈希地址處。

要解決哈希沖突閉散列方法主要有兩個:線性探測與二次探測。

在這里,我將線性探測的原理用下圖表述:

java數據結構中哈希表的線性探測算法是什么

線性探測

java數據結構中哈希表的線性探測算法是什么

線性探測代碼如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

#include<string>

//線性探測的特化處理可以處理自定義類型的數據
enum State
{
   EMPTY,//該位置未存放元素
   DELETE,//該位置元素已被刪除
   EXIST,//該位置存在元素
};

//處理基本類型
template<class K>
struct DefaultFuncer
{
    size_t operator()(const K& key)
    {
        return key;
    }
};

//處理自定義類型
template<>
struct DefaultFuncer<string>
{
    size_t value = 0;
    size_t operator()(const string& str)
    {
        for (int i = 0; i < str.size(); i++)
        {
            value += str[i];
        }
        return value;
    }    
};


template<class K, template<class>class HashFuncer = DefaultFuncer>
class HashTable
{
public:
    HashTable()
        :_size(0)
        , _capacity(0)
        , _state(NULL)
        , _table(NULL)
    {}

       HashTable(size_t size)
            :_size(0)
            , _capacity(size)
            , _state(new State[size])
            , _table(new K[size])
        {
            for (int i = 0; i < _capacity; i++)//全部狀態初始化成EMPTY
            {
                _state[i] = EMPTY;
            }
        }


        //線性探測計算出元素存放位置(假設不哈希沖突)
        int _HashFunc(const K& key)
        {
            HashFuncer<K> hf;
            return hf(key) % _capacity;
    
            //匿名對象調用operator()
            /*return HashFuncer<K>()(key) % _capacity;*/
        }
    
        void Swap(HashTable<K> tmp)
        {
            swap(_size, tmp._size);
            swap(_capacity, tmp._capacity);
            swap(_state, tmp._state);
            swap(_table, tmp._table);
        }
    
    
        void _CheckCapacity()
        {                
            HashTable<K> tmp(2*_capacity);
            for (int i = 0; i < _capacity; i++)
            {
                tmp.Insert(_table[i]);
            }
            Swap(tmp);
        }
        
    
        bool Insert(const K& key)
        {
            //靜態哈希表
            /*if (_size == _capacity)
            {
                cout<<"HashTable is full!"<<endl;
                return false;
            }*/
    
            //動態哈希表
            //高效哈希表的載荷因子大概穩定在0.7-0.8較好
            if (10 * _size >= 7 * _capacity)
            {
                _CheckCapacity();
            }
    
            int index = _HashFunc(key);
        
            while (_state[index] == EXIST)
            {        
                index++;
                if (index == _capacity)
                {
                    index = 0;
                }
            }
    
            _table[index] = key;
            _state[index] = EXIST;
            _size++;
            return true;    
        }
    
    
        int Find(const K& key)
        {
            int index = _HashFunc(key);
            while (_state[index] == EXIST || _state[index]== DELETE)
            //while(_state[index] != EMPTY)    //空狀態找不到,非空狀態找得到
            {
                if (_table[index] == key && _state[index] == EXIST)
                {
                    return index;
                }
                ++index;
                if (index == _capacity)
                {
                    index = 0;
                }
            }
            return -1;    
        }
    
    
        bool Remove(const K& key)
        {
            int index = Find(key);
            if (index != -1)
            {
                _state[index] = DELETE;
                --_size;
                return true;
            }
            return false;
        }
    
    
        void PrintTable()
        {
            for (int i = 0; i < _capacity; i++)
            {
                if (_state[i] == EXIST )
                {
                    cout << i << "(EXIST):" << _table[i] << endl;
                }
                /*我將DELETE狀態元素也打印出來,便于觀察。
                而Insert處理時,DELETE狀態下的位置可以插上新的元素*/
                else if (_state[i] == DELETE)
                {
                    cout << i << "(DELETE):" << _table[i] << endl;
                }
                else
                {
                    cout << i << "(EMPTY):" << _table[i] << endl;
                }
            }
        }

private:
        size_t _size;//實際存放元素個數
        size_t _capacity;//哈希表長度
        State* _state;
        K* _table;
};


//POD(基本類型)的測試用例
void TestHashTablePOD()
{
    HashTable<int> ht(10);
    ht.Insert(89);
    ht.Insert(18);
    ht.Insert(49);
    ht.Insert(58);
    ht.Insert(9);
    ht.PrintTable();

    int ret = ht.Find(89);
    cout << ret << endl; 

    ht.Remove(89);
    ht.PrintTable();

    ht.Remove(18);
    ht.PrintTable();
}


//自定義類型的測試用例
void TestHashTable()
{
    HashTable<string,DefaultFuncer> ht(10);
    ht.Insert("信息化");
    ht.Insert("時代");
    ht.Insert("電腦");
    ht.Insert("測試工程師");
    ht.PrintTable();

    int ret = ht.Find("測試工程師");
    cout << ret << endl;

    ht.Remove("電腦");
    ht.PrintTable();

    ht.Remove("時代");
    ht.PrintTable();
}


int main()
{
    TestHashTable();
    system("pause");
    return 0;
}

以上就是java數據結構中哈希表的線性探測算法是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女