Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 91久久国产视频,国产久7精品视频,国产在线观看网站

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Redis6五大常用數據類型-哈希(Hash)

          Redis6五大常用數據類型-哈希(Hash)
          redis命令中文參考網站:http://www.redis.cn/commands.html
          redis命令英文參考網站:https://redis.io/commands
          Redis目前支持5種數據類型:
          1. String(字符串)
          2. List(列表)
          3. Hash(字典)
          4. Set(集合)
          5. Sorted Set(有序集合)

          希(Hash)

          哈希(hash)或者叫散列類型(hash),它是一個 string 類型的 field(字段) 和 value(值) 的映射表,其特別適合用于存儲對象,類似于Java中的Map。其結構如下圖:value部分指的就是hash部分

          Hash存儲結構示意圖

          常用命令列表

          命令

          描述

          hset key field value [field value ...]

          設置 key 指定的哈希集中一個或多個字段field的值value。在最新Redis6中hset/hmset命令都可以一次性設置多個field-value

          hmset key field value [field value ...]

          設置 key 指定的哈希集中一個或多個字段field的值value。在最新Redis6中hset/hmset命令都可以一次性設置多個field-value

          het key field

          返回 key 指定的哈希集中該字段filed所關聯的值value

          hgetall key

          返回 key 指定的哈希集中所有的字段和值

          hexists key field

          判斷key指定的哈希集中的字段filed字段是否存在(如果存在則返回1,否則返回0(如果鍵不存在也會返回0))。

          hsetnx key field value

          當key指定的哈希集中,字段filed不存在時賦值value,如果字段已經存在,hsetnx命令將不執行任何操作

          hdel key field [field ...]

          刪除key指定哈希集中的一個或多個字段filed

          hincrby key field increment

          增加 key 指定的哈希集中指定字段filed的數值value。如果 key 不存在,會創建一個新的哈希集并與 key 關聯。如果字段filed不存在,則字段的值在該操作執行前被設置為 0,然后執行增加increment操作。HINCRBY 支持的值的范圍限定在 64位 有符號整數

          hvals key

          獲取哈希集中所有字段filed對應的值value。

          hincrbyfloat key field increment

          為指定key的hash的field字段值執行float類型的increment加操作。如果field不存在,則在執行該操作前設置為0,然后執行增加increment操作。

          hkeys key

          獲取指定key對應的哈希集中所有的字段filed

          hlenkey

          獲取指定key對應的哈希集中字段filed數量

          常用命令演示

          以下命令演示以存儲User對象為例

          public class User{
              private String name;
              private int age;
              private String address;
          }

          user對象存儲示意圖

          1.hset/ hmset key field value [field value ...]

          設置 key 指定的哈希集中一個或多個字段field的值value。在最新Redis6中hset/hmset命令都可以一次性設置多個field-value

          hset返回值說明:如果字段是哈希表中的一個新建字段,并且值設置成功,返回 1 。 如果哈希表中域字段已經存在且舊值已被新值覆蓋,返回 0 。

          hmset返回值說明:如果命令執行成功,返回 OK 。

          127.0.0.1:6379> hset user:1 name xiaoming age 18 address beijing
          (integer) 3 
          127.0.0.1:6379> hmset user:2 name xiaohong age 17 address tianjin
          OK

          2.het key field

          返回 key 指定的哈希集中該字段filed所關聯的值value 。

          127.0.0.1:6379> hget user:1 name
          "xiaoming"

          3.hgetall key

          返回 key 指定的哈希集中所有的字段filed和值 value 。

          127.0.0.1:6379> hgetall user:1
          1) "name"
          2) "xiaoming"
          3) "age"
          4) "18"
          5) "address"
          6) "beijing"
          127.0.0.1:6379> hgetall user:2
          1) "name"
          2) "xiaohong"
          3) "age"
          4) "17"
          5) "address"
          6) "tianjin"

          4.hvals key

          獲取哈希集中所有字段filed對應的值value。

          127.0.0.1:6379> hgetall user:2 //返回 user:2 指定的哈希集中所有的字段filed和值 value 。
          1) "name"
          2) "xiaohong"
          3) "age"
          4) "17"
          5) "address"
          6) "tianjin"
          127.0.0.1:6379> hvals user:2 //獲取user:2 指定的哈希集中所有字段filed對應的值value。  
          1) "xiaohong"
          2) "17"
          3) "tianjin"

          5.hkeys key

          獲取哈希集中所有字段filed。

          127.0.0.1:6379> hgetall user:2//獲取key指定哈希集中的所有filed和value
          1) "name"
          2) "xiaohong"
          3) "age"
          4) "17"
          5) "address"
          6) "tianjin"
          127.0.0.1:6379> hkeys user:2//獲取key指定哈希集中的所有filed
          1) "name"
          2) "age"
          3) "address"
          127.0.0.1:6379> hvals user:2//獲取key指定哈希集中的所有filed對應的value
          1) "xiaohong"
          2) "17"
          3) "tianjin"

          6.hexists key field

          判斷key指定的哈希集中的字段filed字段是否存在(如果存在則返回1,否則返回0(如果鍵不存在也會返回0))。

          127.0.0.1:6379> hget user:1 name
          "xiaoming"
          127.0.0.1:6379> hexists user:1 name
          (integer) 1
          127.0.0.1:6379> hexists user:1 fff//filed字段不存在
          (integer) 0
          127.0.0.1:6379> hexists aaa name//key 不存在
          (integer) 0

          7.hsetnx key field value

          當key指定的哈希集中,字段filed不存在時賦值value,如果字段已經存在,hsetnx命令將不執行任何操作。

          127.0.0.1:6379> hexists user:1 name //存在字段name
          (integer) 1
          127.0.0.1:6379> hget user:1 name //獲取字段name值
          "xiaoming"
          127.0.0.1:6379> hsetnx user:1 name new_xiaoming //給name字段重新賦值
          (integer) 0
          127.0.0.1:6379> hget user:1 name //再獲取字段name值
          "xiaoming"

          8.hdel key field [field ...]

          刪除key指定哈希集中的一個或多個字段filed 。

          127.0.0.1:6379> hgetall user:1 //獲取刪除前user:1 對應的hash集
          1) "name"
          2) "xiaoming"
          3) "age"
          4) "18"
          5) "address"
          6) "beijing"
          127.0.0.1:6379> hdel user:1 name//刪除哈希集中的name字段
          (integer) 1
          127.0.0.1:6379> hgetall user:1//獲取刪除后user:1 對應的hash集
          1) "age"
          2) "18"
          3) "address"
          4) "beijing"

          9.hincrby key field increment

          增加 key 指定的哈希集中指定字段filed的數值value。如果 key 不存在,會創建一個新的哈希集并與 key 關聯。如果字段filed不存在,則字段的值在該操作執行前被設置為 0,然后執行增加increment操作。HINCRBY 支持的值的范圍限定在 64位 有符號整數。

          127.0.0.1:6379> hget user:1 age
          "18"
          127.0.0.1:6379> hincrby user:1 age 10
          (integer) 28
          127.0.0.1:6379> hget user:1 age
          "28"

          10.hincrbyfloat key field increment

          為指定key的hash的field字段值執行float類型的increment加操作。如果field不存在,則在執行該操作前設置為0,然后執行增加increment操作。

          127.0.0.1:6379> hget user:1 age
          "28"
          127.0.0.1:6379> hincrbyfloat user:1 age 10.2
          "38.2"
          127.0.0.1:6379> hget user:1 age
          "38.2"

          11.hlen key

          獲取指定key對應的哈希集中字段filed數量。

          127.0.0.1:6379> hkeys user:2//查看指定Key中的字段
          1) "name"
          2) "age"
          3) "address"
          127.0.0.1:6379> hlen user:2//獲取指定key對應的哈希集中字段filed數量。
          (integer) 3



          曾經以為,自己很勇敢,很堅強,不怕流淚,不畏痛苦。誰知,遇到傷心,遭遇痛苦,一樣會流淚,一樣會哭泣。

          vaScript 中沒有專門的 Hash 類型,但是可以使用 JavaScript 的對象(Object)來模擬 Hash 表的功能。在 JavaScript 中,對象是一種無序的鍵值對集合,每個鍵對應一個值。

          可以使用對象的鍵來實現類似于 Hash 表的功能,其中鍵通常是字符串或數字,值可以是任何 JavaScript 數據類型。例如,可以創建一個包含一些字符串鍵和相應值的對象,類似于一個 Hash 表:

          var hash={
            'key1': 'value1',
            'key2': 'value2',
            'key3': 'value3'
          };
          

          可以使用對象的點語法或方括號語法來訪問鍵對應的值:

          console.log(hash.key1); // 輸出 "value1"
          console.log(hash['key2']); // 輸出 "value2"
          

          可以通過添加、刪除、修改對象的鍵值對來模擬 Hash 表的操作。例如,可以使用以下代碼將新的鍵值對添加到 hash 對象中:

          hash['key4']='value4';
          

          可以使用 delete 關鍵字刪除 hash 對象中的鍵值對:

          delete hash['key3'];
          

          需要注意的是,JavaScript 中的對象是一種引用類型,因此對一個對象的引用進行修改會影響所有引用該對象的變量。在使用對象作為 Hash 表時,也需要注意這一點。

          • . 哈希表的基本思想
          • 2. 哈希表的相關基本概念
          • 3. 哈希表的實現方法
          • 4. 哈希表“定址”的方法
          • 5. 哈希表“解決沖突”的方法
          • 6. 哈希表“定址”和“解決沖突”之間的權衡
          • 7. 哈希表實例

          哈希表(Hash Table)是一種特殊的數據結構,它最大的特點就是可以快速實現查找、插入和刪除。因為它獨有的特點,Hash表經常被用來解決大數據問題,也因此被廣大的程序員所青睞。為了能夠更加靈活地使用Hash來提高我們的代碼效率,今天,我們就談一談Hash的那點事。

          1. 哈希表的基本思想

          我們知道,數組的最大特點就是:尋址容易,插入和刪除困難;而鏈表正好相反,尋址困難,而插入和刪除操作容易。那么如果能夠結合兩者的優點,做出一種尋址、插入和刪除操作同樣快速容易的數據結構,那該有多好。這就是哈希表創建的基本思想,而實際上哈希表也實現了這樣的一個“夙愿”,哈希表就是這樣一個集查找、插入和刪除操作于一身的數據結構。

          回到頂部

          2. 哈希表的相關基本概念

          在介紹Hash之前,首先我們要搞明白幾個概念:

          哈希表(Hash Table):也叫散列表,是根據關鍵碼值(Key-Value)而直接進行訪問的數據結構,也就是我們常用到的map。

          哈希函數:也稱為是散列函數,是Hash表的映射函數,它可以把任意長度的輸入變換成固定長度的輸出,該輸出就是哈希值。哈希函數能使對一個數據序列的訪問過程變得更加迅速有效,通過哈希函數數據元素能夠被很快的進行定位。

          哈希表和哈希函數的標準定義:

          • 若關鍵字為k,則其值存放在f(k)的存儲位置上。由此,不需比較便可直接取得所查記錄。稱這個對應關系f為哈希函數,按這個思想建立的表為哈希表。

          設所有可能出現的關鍵字集合記為U(簡稱全集)。實際發生(即實際存儲)的關鍵字集合記為K(|K|比|U|小得多)。

          散列方法是使用函數h將U映射到表T[0..m-1]的下標上(m=O(|U|))。這樣以U中關鍵字為自變量,以h為函數的運算結果就是相應結點的存儲地址。從而達到在O(1)時間內就可完成查找。

          其中:

          ① h:U→{0,1,2,…,m-1} ,通常稱h為哈希函數(Hash Function)。哈希函數h的作用是壓縮待處理的下標范圍,使待處理的|U|個值減少到m個值,從而降低空間開銷。

          ② T為哈希表(Hash Table)。

          ③ h(Ki)(Ki∈U)是關鍵字為Ki結點存儲地址(亦稱散列值或散列地址)。

          ④ 將結點按其關鍵字的哈希地址存儲到哈希表中的過程稱為散列(Hashing)

          1)沖突:

          兩個不同的關鍵字,由于散列函數值相同,因而被映射到同一表位置上。該現象稱為沖突(Collision)或碰撞。發生沖突的兩個關鍵字稱為該散列函數的同義詞(Synonym)。

          2)安全避免沖突的條件:

          最理想的解決沖突的方法是安全避免沖突。要做到這一點必須滿足兩個條件:

          ①其一是|U|≤m

          ②其二是選擇合適的散列函數。

          這只適用于|U|較小,且關鍵字均事先已知的情況,此時經過精心設計散列函數h有可能完全避免沖突。

          3)沖突不可能完全避免

          通常情況下,h是一個壓縮映像。雖然|K|≤m,但|U|>m,故無論怎樣設計h,也不可能完全避免沖突。因此,只能在設計h時盡可能使沖突最少。同時還需要確定解決沖突的方法,使發生沖突的同義詞能夠存儲到表中。

          4)影響沖突的因素

          沖突的頻繁程度除了與h相關外,還與表的填滿程度相關。

          設m和n分別表示表長和表中填入的結點數,則將α=n/m定義為散列表的裝填因子(Load Factor)。α越大,表越滿,沖突的機會也越大。通常取α≤1。

          回到頂部

          3. 哈希表的實現方法

          我們之前說了,哈希表是一個集查找、插入和刪除操作于一身的數據結構。那這么完美的數據結構到底是怎么實現的呢?哈希表有很多種不同的實現方法,為了實現哈希表的創建,這些所有的方法都離不開兩個問題——“定址”和“解決沖突”。

          在這里,我們通過詳細地介紹哈希表最常用的方法——取余法(定值)+拉鏈法(解決沖突),來一起窺探一下哈希表強大的優點。

          取余法大家一定不會感覺陌生,就是我們經常說的取余數的操作。

          拉鏈法是什么,“拉鏈”說白了就是“鏈表數組”。我這么一解釋,大家更暈了,啥是“鏈表數組”啊?為了更好地解釋“鏈表數組”,我們用下圖進行解釋:圖中的主干部分是一個順序存儲結構數組,但是有的數組元素為空,有的對應一個值,有的對應的是一個鏈表,這就是“鏈表數組”。比如數組0的位置對應一個鏈表,鏈表有兩個元素“496”和“896”,這說明元素“496”和“896”有著同樣的Hash地址,這就是我們上邊介紹的“沖突”或者“碰撞”。但是“鏈表數組”的存儲方式很好地解決了Hash表中的沖突問題,發生沖突的元素會被存在一個對應Hash地址指向的鏈表中。實際上,“鏈表數組”就是一個指針數組,每一個指針指向一個鏈表的頭結點,鏈表可能為空,也可能不為空。

          說完這些,大家肯定已經理解了“鏈表數組”的概念,那我們就一起看看Hash表是如何根據“取余法+拉鏈法”構建的吧。

          將所有關鍵字為同義詞的結點鏈接在同一個鏈表中。若選定的散列表長度為m,則可將散列表定義為一個由m個頭指針組成的指針數組T[0..m-1]。凡是散列地址為i的結點,均插入到以T[i]為頭指針的單鏈表中。T中各分量的初值均應為空指針。在拉鏈法中,裝填因子α可以大于1,但一般均取α≤1。

          舉例說明拉鏈法的執行過程,設有一組關鍵字為(26,36,41,38,44,15,68,12,6,51),用取余法構造散列函數,初始情況如下圖所示:

          最終結果如下圖所示:

          理解了Hash表的創建,那根據建立的Hash表進行查找就很容易被理解了。

          查找操作,如果理解了插入和刪除,查找操作就比較簡單了,令待查找的關鍵字是x,也可分為幾種情況:

          1)x所屬的Hash地址未被占用,即不存在與x相同的Hash地址關鍵字,當然也不存在x了;

          2)x所屬的Hash地址被占用了,但它所存的關鍵不屬于這個Hash地址,與1)相同,不存在與x相同Hash地址的關鍵字;

          3)x所屬的Hash地址被占用了,且它所存的關鍵屬于這個Hash地址,即存在與x相同sHash地址的關鍵字,只是不知這個關鍵字是不是x,需要進一步查找。

          由此可見,Hash表插入、刪除和插入操作的效率都相當的高。

          思考一個問題:如果關鍵字是字符串怎么辦?我們怎么根據字符串建立Hash表?

          通常都是將元素的key轉換為數字進行散列,如果key本身就是整數,那么散列函數可以采用keymod tablesize(要保證tablesize是質數)。而在實際工作中經常用字符串作為關鍵字,例如身姓名、職位等等。這個時候需要設計一個好的散列函數進程處理關鍵字為字符串的元素。參考《數據結構與算法分析》第5章,有以下幾種處理方法:

          方法1:將字符串的所有的字符的ASCII碼值進行相加,將所得和作為元素的關鍵字。設計的散列函數如下所示:

          int hash(const string& key,int tablesize)
          {
           int hashVal=0;
           for(int i=0;i<key.length();i++)
           hashVal +=key[i];
           return hashVal % tableSize;
          }
          

          此方法的缺點是不能有效的分布元素,例如假設關鍵字是有8個字母構成的字符串,散列表的長度為10007。字母最大的ASCII碼為127,按照方法1可得到關鍵字對應的最大數值為127×8=1016,也就是說通過散列函數映射時只能映射到散列表的槽0-1016之間,這樣導致大部分槽沒有用到,分布不均勻,從而效率低下。

          方法2:假設關鍵字至少有三個字母構成,散列函數只是取前三個字母進行散列。設計的散列函數如下所示:

          int hash(const string& key,int tablesize)
          {
           //27 represents the number of letters plus the blank
           return (key[0]+27*key[1]+729*key[2])%tablesize;
          }
          

          該方法只是取字符串的前三個字符的ASCII碼進行散列,最大的得到的數值是2851,如果散列的長度為10007,那么只有28%的空間被用到,大部分空間沒有用到。因此如果散列表太大,就不太適用。

          方法3:借助Horner's 規則,構造一個質數(通常是37)的多項式,(非常的巧妙,不知道為何是37)。計算公式為:key[keysize-i-1]*37i, 0<=i<keysize求和。設計的散列函數如下所示:

          int hash(const string & key,int tablesize)
          {
           int hashVal=0;
           for(int i=0;i<key.length();i++)
           hashVal=37*hashVal + key[i];
           hashVal %=tableSize;
           if(hashVal<0) //計算的hashVal溢出
           hashVal +=tableSize;
           return hashVal;
          }
          

          該方法存在的問題是如果字符串關鍵字比較長,散列函數的計算過程就變長,有可能導致計算的hashVal溢出。針對這種情況可以采取字符串的部分字符進行計算,例如計算偶數或者奇數位的字符。

          回到頂部

          4. 哈希表“定址”的方法

          其實常用的“定址”的手法有“五種”:

          1)直接定址法

          很容易理解,key=Value+C;這個“C"是常量。Value+C其實就是一個簡單的哈希函數。

          2)除法取余法

          key=value%C

          3)數字分析法

          這種蠻有意思,比如有一組value1=112233,value2=112633,value3=119033,針對這樣的數我們分析數中間兩個數比較波動,其他數不變。那么我們取key的值就可以是key1=22,key2=26,key3=90。

          4)平方取中法

          5)折疊法

          舉個例子,比如value=135790,要求key是2位數的散列值。那么我們將value變為13+57+90=160,然后去掉高位“1”,此時key=60,哈哈,這就是他們的哈希關系,這樣做的目的就是key與每一位value都相關,來做到“散列地址”盡可能分散的目地。

          影響哈希查找效率的一個重要因素是哈希函數本身。當兩個不同的數據元素的哈希值相同時,就會發生沖突。為減少發生沖突的可能性,哈希函數應該將數據盡可能分散地映射到哈希表的每一個表項中。

          回到頂部

          5. 哈希表“解決沖突”的方法

          Hash表解決沖突的方法主要有以下兩種:

          1)開放地址法

          如果兩個數據元素的哈希值相同,則在哈希表中為后插入的數據元素另外選擇一個表項。當程序查找哈希表時,如果沒有在第一個對應的哈希表項中找到符合查找要求的數據元素,程序就會繼續往后查找,直到找到一個符合查找要求的數據元素,或者遇到一個空的表項。

          開放地址法包括線性探測、二次探測以及雙重散列等方法。其中線性探測法示意圖如下:

          散列過程如下圖所示:

          2)鏈地址法

          將哈希值相同的數據元素存放在一個鏈表中,在查找哈希表的過程中,當查找到這個鏈表時,必須采用線性查找方法。

          回到頂部

          6. 哈希表“定址”和“解決沖突”之間的權衡

          雖然哈希表是在關鍵字和存儲位置之間建立了對應關系,但是由于沖突的發生,哈希表的查找仍然是一個和關鍵字比較的過程,不過哈希表平均查找長度比順序查找要小得多,比二分查找也小。

          查找過程中需和給定值進行比較的關鍵字個數取決于下列三個因素:哈希函數、處理沖突的方法和哈希表的裝填因子。

          哈希函數的"好壞"首先影響出現沖突的頻繁程度,但如果哈希函數是均勻的,則一般不考慮它對平均查找長度的影響。

          對同一組關鍵字,設定相同的哈希函數,但使用不同的沖突處理方法,會得到不同的哈希表,它們的平均查找長度也不同。

          一般情況下,處理沖突方法相同的哈希表,其平均查找長度依賴于哈希表的裝填因子α。顯然,α越小,產生沖突的機會就越大;但α過小,空間的浪費就過多。通過選擇一個合適的裝填因子α,可以將平均查找長度限定在一個范圍內。

          總而言之,哈希表“定址”和“解決沖突”之間的權衡決定了哈希表的性能。

          回到頂部

          7. 哈希表實例

          一個哈希表實現的C++實例,在此設計的散列表針對的是關鍵字為字符串的元素,采用字符串散列函數方法3進行設計散列函數,采用鏈接方法處理碰撞,然后采用根據裝載因子(指定為1,同時將n個元素映射到一個鏈表上,即n==m時候)進行再散列。采用C++,借助vector和list,設計的hash表框架如下:

          template <class T>
          class HashTable
          {
          public:
           HashTable(int size=101);
           int insert(const T& x);
           int remove(const T& x);
           int contains(const T& x);
           void make_empty();
           void display()const;
          private:
           vector<list<T> > lists;
           int currentSize;//當前散列表中元素的個數
           int hash(const string& key);
           int myhash(const T& x);
           void rehash();
          };
          

          實現的完整程序如下所示:

          #include <iostream>
          #include <vector>
          #include <list>
          #include <string>
          #include <cstdlib>
          #include <cmath>
          #include <algorithm>
          using namespace std;
          int nextPrime(const int n);
          template <class T>
          class HashTable
          {
          public:
           HashTable(int size=101);
           int insert(const T& x);
           int remove(const T& x);
           int contains(const T& x);
           void make_empty();
           void display()const;
          private:
           vector<list<T> > lists;
           int currentSize;
           int hash(const string& key);
           int myhash(const T& x);
           void rehash();
          };
          template <class T>
          HashTable<T>::HashTable(int size)
          {
           lists=vector<list<T> >(size);
           currentSize=0;
          }
          template <class T>
          int HashTable<T>::hash(const string& key)
          {
           int hashVal=0;
           int tableSize=lists.size();
           for(int i=0;i<key.length();i++)
           hashVal=37*hashVal+key[i];
           hashVal %=tableSize;
           if(hashVal < 0)
           hashVal +=tableSize;
           return hashVal;
          }
          template <class T>
          int HashTable<T>:: myhash(const T& x)
          {
           string key=x.getName();
           return hash(key);
          }
          template <class T>
          int HashTable<T>::insert(const T& x)
          {
           list<T> &whichlist=lists[myhash(x)];
           if(find(whichlist.begin(),whichlist.end(),x) !=whichlist.end())
           return 0;
           whichlist.push_back(x);
           currentSize=currentSize + 1;
           if(currentSize > lists.size())
           rehash();
           return 1;
          }
          template <class T>
          int HashTable<T>::remove(const T& x)
          {
           typename std::list<T>::iterator iter;
           list<T> &whichlist=lists[myhash(x)];
           iter=find(whichlist.begin(),whichlist.end(),x);
           if( iter !=whichlist.end())
           {
           whichlist.erase(iter);
           currentSize--;
           return 1;
           }
           return 0;
          }
          template <class T>
          int HashTable<T>::contains(const T& x)
          {
           list<T> whichlist;
           typename std::list<T>::iterator iter;
           whichlist=lists[myhash(x)];
           iter=find(whichlist.begin(),whichlist.end(),x);
           if( iter !=whichlist.end())
           return 1;
           return 0;
          }
          template <class T>
          void HashTable<T>::make_empty()
          {
           for(int i=0;i<lists.size();i++)
           lists[i].clear();
           currentSize=0;
           return 0;
          }
          template <class T>
          void HashTable<T>::rehash()
          {
           vector<list<T> > oldLists=lists;
           lists.resize(nextPrime(2*lists.size()));
           for(int i=0;i<lists.size();i++)
           lists[i].clear();
           currentSize=0;
           for(int i=0;i<oldLists.size();i++)
           {
           typename std::list<T>::iterator iter=oldLists[i].begin();
           while(iter !=oldLists[i].end())
           insert(*iter++);
           }
          }
          template <class T>
          void HashTable<T>::display()const
          {
           for(int i=0;i<lists.size();i++)
           {
           cout<<i<<": ";
           typename std::list<T>::const_iterator iter=lists[i].begin();
           while(iter !=lists[i].end())
           {
           cout<<*iter<<" ";
           ++iter;
           }
           cout<<endl;
           }
          }
          int nextPrime(const int n)
          {
           int ret,i;
           ret=n;
           while(1)
           {
           int flag=1;
           for(i=2;i<sqrt(ret);i++)
           if(ret % i==0)
           {
           flag=0;
           break;
           }
           if(flag==1)
           break;
           else
           {
           ret=ret +1;
           continue;
           }
           }
           return ret;
          }
          class Employee
          {
          public:
           Employee(){}
           Employee(const string n,int s=0):name(n),salary(s){ }
           const string & getName()const { return name; }
           bool operator==(const Employee &rhs) const
           {
           return getName()==rhs.getName();
           }
           bool operator !=(const Employee &rhs) const
           {
           return !(*this==rhs);
           }
           friend ostream& operator <<(ostream& out,const Employee& e)
           {
           out<<"("<<e.name<<","<<e.salary<<") ";
           return out;
           }
          private:
           string name;
           int salary;
          };
          int main()
          {
           Employee e1("Tom",6000);
           Employee e2("Anker",7000);
           Employee e3("Jermey",8000);
           Employee e4("Lucy",7500);
           HashTable<Employee> emp_table(13);
           emp_table.insert(e1);
           emp_table.insert(e2);
           emp_table.insert(e3);
           emp_table.insert(e4);
           cout<<"Hash table is: "<<endl;
           emp_table.display();
           if(emp_table.contains(e4)==1)
           cout<<"Tom is exist in hash table"<<endl;
           if(emp_table.remove(e1)==1)
           cout<<"Removing Tom form the hash table successfully"<<endl;
           if(emp_table.contains(e1)==1)
           cout<<"Tom is exist in hash table"<<endl;
           else
           cout<<"Tom is not exist in hash table"<<endl;
           //emp_table.display();
           exit(0);
          }
          

          作者:Poll的筆記

          原文:http://www.cnblogs.com/maybe2030/p/4719267.html


          主站蜘蛛池模板: 久久人妻内射无码一区三区| 国产在线一区二区三区| 国产精品特级毛片一区二区三区| 精品日韩一区二区三区视频| 一区二区三区精品| 精品视频一区二区三区在线观看| 国产一区二区久久久| 久久99精品波多结衣一区| 国产亚洲一区区二区在线| 国产AV午夜精品一区二区三| 国产精品亚洲专区一区| 无码少妇丰满熟妇一区二区| 风间由美性色一区二区三区 | 国语精品一区二区三区| 国产一区二区三区免费视频| 欧美日韩国产免费一区二区三区 | 国产精品高清一区二区三区| 日本一区午夜艳熟免费| 久久精品国产一区二区三区不卡| 日韩一区二区三区免费播放| 久久国产一区二区| 色屁屁一区二区三区视频国产| 手机看片一区二区| 国产AV一区二区三区无码野战| 久久国产午夜一区二区福利| 精品永久久福利一区二区| 精品国产a∨无码一区二区三区| 亚洲熟妇av一区| 一区二区亚洲精品精华液| 色一情一乱一伦一区二区三欧美 | 久久国产一区二区| 中文字幕无线码一区2020青青| 人妻AV一区二区三区精品 | 亚洲AV无码一区二区三区在线观看 | 亚洲av鲁丝一区二区三区| 久久国产午夜一区二区福利| 波多野结衣中文一区| 亚洲一区二区三区久久| 福利国产微拍广场一区视频在线 | 一区二区三区在线免费观看视频| www一区二区www免费|