1. 程式人生 > 實用技巧 >VM安裝的虛擬機器如何在區域網內互相訪問

VM安裝的虛擬機器如何在區域網內互相訪問

雜湊表

散列表,以 key-value 儲存資料的資料結構。可以理解成一種高階陣列 a[key] = value,陣列的下標可以是大整數、浮點數等等。

雜湊函式

如果 key 不是小整數,不能直接作為陣列座標,就需要使用雜湊函式根據 key 來計算 value 的索引,即計算 value 存放的位置。例如 key 為大整數時可使用 \(x\bmod M\) 來作為索引。雜湊函式為 f,那麼鍵值對 (key,value) 應該放在 a[f(key)] 上,即對 key 做對映,對映到陣列下標上。

衝突

如果對於任意 key,雜湊函式計算出來的索引都不相同,那隻用根據索引把 (key,value) 放到對應的位置就行了。但實際上,常常會出現兩個不同的 key,他們用雜湊函式計算出來的索引是相同的。這時候就需要一些方法來處理衝突。

拉鍊法

不同於陣列,一個 a[i] 上儲存一個連結串列,儲存所有 \(f(key)=i\) 的 value。插入鍵值對時若多個 key 索引相同,則都插入到那個連結串列裡;查詢時對對應位置的連結串列掃描,比較裡面的 key 和查詢的 key 是否一致。注意我們計算了 f(key) 同時也保留了 key,f(key) 相同比較 key 和給定的 key 的過程不存在衝突。

如果比較 key 的時間複雜度比較高,例如 string 間的比較,還可以使用雜湊函式做另一個引數 pre。若一些鍵值對存在於 a[f(key)] 中,查詢給定 key,則比較時先比較當前鍵值對的 pre 和給定 key 的 pre。也就是說定義另一個雜湊函式 \(g(x)=pre\)

,插入鍵值對時儲存 pre,查詢某一 key 時也先計算 pre。這樣避免了比較時間的浪費。

如果 \(f(x)\in[1,M]\),雜湊表大小為 \(N\),那麼一次插入/查詢需要進行期望 \(O(\frac{N}{M})\) 次比較。

實現

給一個 key 為整數的實現:

const int kS = 1000003;
const int kM = 90007;
struct HashTable {
	struct HashNode {
		int key, value, nxt;
	} data[kS];
	int head[kM], cnt;
	inline int f(int x) {
		return (x % kM + kM) % kM;
	} // 雜湊函式根據 key 來設計
	inline int get(int key) {
		for(int i = head[f(key)]; i; i = data[i].nxt)
			if(data[i].key == key) return data[i].value;
		return -1;	
	}
	inline void modify(int key, int value) {
		for(int i = head[f(key)]; i; i = data[i].nxt)
			if(data[i].key == key) return data[i].value = value, void();
	}
	inline void insert(int key, int value) {
		if(get(key) != -1) return;
		data[++cnt] = (HashNode){key, value, head[f(key)]};
		head[f(key)] = cnt;
	}
} mp;