閉雜湊主要就是需要注意一下「墓碑」的操作,其他的其實都簡單。asl的計算忘了,找了兩道題都沒算對,這才是我不寫的真正原因…**裡是裝13用的…
#include
using
namespace
std;
/* 雜湊表:
雜湊表(hash table,也叫雜湊表),是根據關鍵碼值(key value)而直接進行訪問的資料結構。也就是說,它通過把關
鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。
兩種方式:
閉雜湊:若雜湊函式求出來相同的對映值,則把重複的元素存放在雜湊表的另乙個槽裡。
開雜湊:把發生衝突的關鍵碼儲存在雜湊表主表之外。
閉雜湊:
使用線性探測法舉例:對於a、b、c三個資料計算出來的key都是0。在插入的時候應該如下:
插入:
索引: 0 1 2 3
插入a: a
插入b: b(衝突,後移)
b插入c: c(衝突,後移)
c(衝突,後移)
c最終結果: a b c
查詢:
查詢的時候也是計算value得到key,然後使用和建立時相同的探測方法來向後尋值,直至找到或者遇到空。
比如查詢b,計算得到key為0,在第0位未尋到b,後移在第一位尋找到了b。
比如查詢d,計算得到key為0,在第0位未尋到d,後移三次之後遇到了空位,說明雜湊表裡沒有這個值。
刪除:刪除的時候不能簡單的把資料存放的位置置空。因為這可能影響到其他資料,
比如我刪除b,把第2位置空之後發現。然後我想查詢c,通過計算得到key是0,然後向後移動一位遇到空位,返回未找到。
實際上雜湊表裡是存在c的。所以在刪除的時候不能把原資料位置置空,而是設立乙個「墓碑」。
墓碑:標誌著這個槽之前存放過資料但現在不再使用了。
改進插入:
其實就乙個問題,插入的時候如果遇到了墓碑能直接插入嗎?答案當然是不能。正確的做法是遇到墓碑後記錄
第乙個墓碑所在的位置,然後向後遍歷直至遇到真正的空位置,在這個過程中如過存在資料和待插入資料一致。
則表示資料已存在,插入失敗。如果直接迴圈到了真正的空位置,表面資料不存在,把資料插入第乙個墓碑的
位置,如果全程為出現墓碑,插在當前空位置中。
開雜湊:
開雜湊就是陣列加鍊表的形式。從每個索引位置中引出乙個鍊錶,用以儲存發生衝突時的資料。這個是不需要設定墓碑的。
實現:下面的實現是基於閉雜湊的實現。基於開雜湊的實現請看我的另一篇文章。
至於說asl的計算等理論性問題可以去mooc或者在資料上尋找相關解釋,我的csdn部落格整個
dsa(data structure and algorithm)文集都是側重於計算機相關專業資料結構與演算法課程中遇到的演算法的實現。
*/#define max 1010
#define tombstone 99999999
#define mynull -99999999
class node
};//雜湊值:最簡單的取餘法
int getkey(int val)
//衝突解決方案:線性探測法
int getdis()
//插入
bool insert(node data, int val)
data.values[tomb == -1 ? key : tomb] = val;
return
true;
}//刪除
bool del(node data, int val)
key += getdis();
}return
false;
}//查詢
bool getval(node data, int val)
return
false;
}int main()
雜湊表(閉雜湊 拉鍊法 雜湊桶)
雜湊表,也稱雜湊表,是一種通過key值來直接訪問在記憶體中的儲存的資料結構。它通過乙個關鍵值的函式 被稱為雜湊函式 將所需的資料對映到表中的位置來訪問資料。關於雜湊表,主要為以下幾個方面 一 雜湊表的幾種方法 1 直接定址法 取關鍵字key的某個線性函式為雜湊位址,如hash key key 或 h...
雜湊閉雜湊實現
一 實現靜態的雜湊表 下面,將給出靜態實現 靜態 define max size 10 typedef enum state templatestruct elem templatebool isline true class hashtable size 0 插入元素 bool insert co...
雜湊之開雜湊,閉雜湊
有沒有一種方法時間複雜度,僅僅o 1 尼,那麼我們就要構造一種儲存結構,通過某種函式是之元素與它對應的關鍵碼之間能建立一一對映的關係,那麼自然通過之中一一對映的關係,我們就可以很快的找到我們需要的元素。所以進入雜湊這個這題首先我們需要乙個我們下標,這個下表在雜湊當中 我們就稱之為雜湊位址。而這個位址...