日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【STL源码剖析读书笔记】【第5章】关联式容器之hashtable

發(fā)布時間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STL源码剖析读书笔记】【第5章】关联式容器之hashtable 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、hashtable在插入、刪除、搜尋操作上具有常數(shù)平均時間的表現(xiàn),不依賴輸入元素的隨機性。

2、hashtable通過hashfunction將元素映射到不同的位置,但當不同的元素通過hash function映射到相同的位置時,便產(chǎn)生了碰撞問題。解決碰撞問題的方法主要有線性探測、二次探測、開鏈法等。

3、線性探測

hash function計算出某個元素的插入位置,而該位置的空間已不可用時,循序往下尋找下一可用位置(到達尾端時繞到頭部繼續(xù)尋找),會產(chǎn)生primary clustering問題。

4、二次探測

hash function計算出某個元素的插入位置為H,而該位置的空間已被占用,就嘗試H+12H+22,會產(chǎn)生secondary clustering問題。

5、開鏈

在每一個表格元素中維護一個listhash function為我們分配某個list,在那個list上進行元素插入、刪除、搜尋等操作。SGI STL解決碰撞問題的方法就是此方法。

6、hashtable節(jié)點定義:

template <class Value>
struct __hashtable_node
{__hashtable_node* next;Value val;
};

7hashtable的迭代器

hashtable迭代器必須永遠維系與整個“buckets vector”的關(guān)系,并記錄目前所知節(jié)點。hashtable的迭代器沒有后退操作,也沒有逆向迭代器。

8、hashtable的數(shù)據(jù)結(jié)構(gòu)

template <class Value, class Key, class HashFcn,class ExtractKey, class EqualKey,class Alloc>

value:節(jié)點的實值類別
?key
:節(jié)點的鍵值類別
?HashFcn
:hash function函數(shù)類別
?ExtractKey
:從節(jié)點中取出鍵值的方法
?EqualKey
:判斷鍵值相同與否的方法
Alloc
:空間配置器,默認使用std::alloc

9hashtable的構(gòu)造與內(nèi)存管理

節(jié)點配置函數(shù)與節(jié)點釋放函數(shù)

node* new_node(const value_type& obj){node* n = node_allocator::allocate();n->next = 0;__STL_TRY {construct(&n->val, obj);return n;}__STL_UNWIND(node_allocator::deallocate(n));}void delete_node(node* n){destroy(&n->val);node_allocator::deallocate(n);}

表格重建操作

resize()
{
表格是否需要重建判斷原則:拿元素個數(shù)和bucket vector的大小來比,如果前者比后者大就重建表格。因此,每個bucket(list)的最大容量和bucket vector的大小相同。如果要重建,找出下一個質(zhì)數(shù)作為vector的大小,建立新的buckets處理每一個舊的bucket{建立一個新節(jié)點指向節(jié)點所指的串行的起始節(jié)點處理每一個舊bucket所含串行的每一個節(jié)點{找出節(jié)點落在哪一個新的bucket內(nèi)令舊bucket指向其所指的串行的下一個節(jié)點將當前節(jié)點插入到新的bucket內(nèi),成為其串行的第一個節(jié)點回到舊bucket所指的待處理串行,準備處理下一個節(jié)點
}
}新舊兩個buckets對調(diào),如果雙方大小不同,大的會變小,小的會變大
離開時釋放temp的內(nèi)存
}

插入操作

insert_unique(const value_type& obj)//不允許元素重復
{resize(num_elements+1);//判斷是否需要重整表格return insert_unique_noresize(obj);
}
insert_unique_noresize(obj)
{計算出obj應位于哪個bucket令first指向bucket對應的串行的頭部如果bucket已經(jīng)被占用,檢查bucket對應的整個鏈表如果發(fā)現(xiàn)鏈表中有相同的元素,就立即返回否則產(chǎn)生新節(jié)點,令新節(jié)點為鏈表的第一個節(jié)點,節(jié)點個數(shù)加1
}
insert_equal(const value_type& obj)//允許元素重復
{resize(num_elements+1);//判斷是否需要重整表格return insert_equal_noresize(obj);
}
insert_equal_noresize(obj)
{計算出obj應位于哪個bucket令first指向bucket對應的串行的頭部如果bucket已經(jīng)被占用,檢查bucket對應的整個鏈表如果發(fā)現(xiàn)鏈表中有相同元素,則產(chǎn)生新節(jié)點,插入目前節(jié)點之后,節(jié)點數(shù)加1返回一個迭代器,指向新節(jié)點進行到這里說明沒有發(fā)現(xiàn)新節(jié)點產(chǎn)生新節(jié)點將新節(jié)點插入到鏈表的頭部,節(jié)點個數(shù)加1返回一個迭代器,指向新節(jié)點
}

10、hash functions

對于字符串,設(shè)計了一個轉(zhuǎn)換函數(shù)

inline size_t __stl_hash_string(const char* s)
{unsigned long h = 0; for ( ; *s; ++s)h = 5*h + *s;return size_t(h);
}

其他大部分hash functions什么也不做,只是返回原值。




轉(zhuǎn)載于:https://www.cnblogs.com/ruan875417/p/4558310.html

總結(jié)

以上是生活随笔為你收集整理的【STL源码剖析读书笔记】【第5章】关联式容器之hashtable的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。