アルゴリズム:ハッシュルックアップ


ハッシュ検索の概念:ハッシュ検索:レコードのストレージアドレスとそのキーの間に明確な対応を確立します。比較せずに、チェックした要素の検索方法を1回のアクセスで取得できます。
ハッシュ関数:記録されたキーと記録されたストレージアドレスの間に確立された対応する関係は、ハッシュ関数と呼ばれます。
ハッシュテーブル:ハッシュ関数を適用し、レコードのキーでテーブルに記録されているアドレスを判別し、このアドレスにレコードを入れます。このようにして形成されたテーブルをハッシュテーブルと呼びます。
ハッシュ関数を使用して検索するプロセスは、ハッシュ検索と呼ばれます。
競合:さまざまなキーワードki、kjの場合。ki!= kjの場合、ただしH(ki)= H(kj)現象。

ハッシュ関数の設計要件:シンプルで、結果を短時間で計算できる必要があります。そして、すべてのキーワードを保存できます。
一般的に、ハッシュ関数の設計として、余り分割して残す方法を使用します。つまり、H(key)= key%p(p <= m、mはテーブルの長さ、pはm以下の素数、または20未満の素因数を含まない)です。この設計は次のとおりです。競合の可能性を減らします。
たとえば、次の一連のキーワードがあります。

12 39 18 24 33 21 ,若p = 9,则他们对应的哈希函数值为:
3  3  0   6  6  3

12、39、21の間で競合が発生し、24と33の間で競合が発生します。対立の可能性が高まります。

残りの方法に加えて、競合現象に対処するため。39、24、33、21を配置するルールを設定する必要があります。一般的に、次のルールがあります
。1。オープンアドレス法。
2.再ハッシュ。
3.チェーンアドレス方式。

オープンアドレス方式:
競合するアドレスのアドレスシーケンスを取得しますH(key):H0、H1 ... HS
Hi = [H(key)+ di]%m、ここでmはハッシュテーブルの長さです。
diが1、2、3 ... m-1の場合、線形検出および再ハッシュと呼ばれ
ます。diが1、-1,4、-4、9、-9、25 ...の場合、二次検出および再散乱と呼ばれます。列
diが乱数をとる場合、それは疑似ランダム検出および再ハッシュと呼ばれます。

キーワードセットが{19,1,23,14,55,68,11,82,36}、m = 11 [テーブル長]であり
、線形検出とハッシュを使用すると、最終結果は次のようになります。

		0	1	2	3	4	5	6	7	8	9	10
		55  1  23   14  68  11  82  36  19
查找次数 1	1	2	1	3	6	2	5	1   

2つの検出とハッシュを使用すると、最終結果は次のようになります。

0	1	2	3	4	5	6	7	8	9	10
55  1   23  14  36  82  68      19      11 

疑似乱数とは、乱数を生成してから検出することです。原理は上記の2つの方法と似ているので、繰り返しません。

チェーンアドレス方式:
同じリンクリスト内の同じハッシュアドレスを持つすべてのレコードをリンクします。上記のキーワードセットを再度想定します。テーブルの後に挿入する方法を使用します。
ここに写真の説明を書いてください
テーブルヘッダーを挿入する方法:一般的に、テーブルの後に挿入する方法
ここに写真の説明を書いてください
検索する必要があり、テーブルヘッダーの挿入は不要であるため、テーブルヘッダーの挿入方法が一般的に採用されます。時間の消費を減らすために

ハッシュ関数がモジュロのキーワードであると仮定すると、ハッシュテーブルはチェーンアドレス方式を使用して競合を解決します。以下に、アルゴリズムの実装を示します。

// 链
class List {
	Node head;
}

// 链中结点
class Node {
	int data;
	Node next;
}

// 用于创建哈希链表
public static List[] createHash(int[] a) {
	List[] lists = new List[11];
	for (int i = 0; i < lists.length; i++) {
		lists[i] = new List();
		lists[i].head = new Node();
	}

	for (int i = 0; i < a.length; i++) {
		int model = a[i] % 11;

		Node next = new Node();
		next.data = a[i];

		Node head = lists[model].head;
		Node node = head.next;
		next.next = node;
		head.next = next;
	}
	return lists;
}

// 查找关键字,返回查找次数
public static int findKey(List[] lists, int key) {
	int index = 0;
	for (int i = 0; i < lists.length; i++) {
		Node head = lists[i].head;
		Node next = head.next;
		while (next != null) {
			if(next.data == key)
				return index;
			index ++;
			next = next.next;
		}
	}
	return -1;
}

int[] a = new int[] { 19, 1, 23, 14, 55, 68, 11, 82, 36 };
int key = 55;
List[] lists = createHash(a);
System.out.println("哈希表内容为:");
for (int i = 0; i < lists.length; i++) {
	Node head = lists[i].head;
	Node next = head.next;
	while (next != null) {
		System.out.print(next.data + "->");
		next = next.next;
	}
	System.out.println();
}
int position = findKey(lists, key);
System.out.println("查找次数为:" + position);

プログラムの実行結果:

哈希表内容为:
11->55->
23->1->
68->
36->14->

82->


19->


查找次数为:1

おすすめ

転載: blog.csdn.net/new_Aiden/article/details/50984931