[リソース構造]TableとHash
12833 ワード
Table
格納されたデータがキーと値のペアで構成されるデータ構造をテーブルと呼ぶ.テーブルに鍵が存在しない値を保存できません.また、すべてのキーは重複しません.表は辞書構造や地図(map)と呼ばれることがある.
探索演算はO(1)の時間的複雑さを有する.
ex)マンションのメールアドレス-番号(キー)、メール(値)
辞書(dictionary)-単語(key)、単語の説明または内容(value)
typedef struct_empInfo {
int empNum; //직원의 고유번호 : key
int age; // 직원의 나이 : value
} EmpInfo;
EmpInfo empInfoArr[1000]; // 직원들의 정보를 저장하기 위해 선언된 배열
上の列をテーブルと呼ぶのはちょっと足りません.テーブルがキーを決定した場合、その上で前回データを見つけることができる必要があります.すなわち,テーブルではキー(key)がデータを検索するツールである.EmpInfo ei;
empInfoArr[ei.empNum] = ei; // 저장
ei = empInfoArr[eNum]; // 탐색
テーブルのキー値empNumは、データをその場所に格納できるようにインデックス値である必要があります.ここでの問題は、従業員が99999999999999であれば、大きな並びが必要で、どのような問題が発生するのでしょうか.
Hash Table
Hash Tableは、関連配列構造を用いてキーに値を格納するデータ構造である.鍵(key)は、ハッシュ関数によってハッシュに変更され、ハッシュ値と一致してリポジトリに格納される.
関連配列構造(関連配列):1つのキーと1つの値1:1に関連する資料構造.したがって、キーを使用して値をエクスポートできます.
こうぞう
ハッシュ関数の例
typedef struct_empInfo {
int empNum; //직원의 고유번호 : key
int age; // 직원의 나이 : value
} EmpInfo;
int getHashValue(int empNum) {
return empNum % 100;
}
例えば、上記のコードとは異なり、社員の固有番号は、入社年度の4つの位置と、入社順の4つの位置からなる.いずれ1000人を超えることになるが、現在は100人以上を採用する可能性がある.したがって、アレイの長さを最小限に抑えるために努力していると仮定し、getHashValue関数で解を得ます.hash関数により広範囲の鍵を小範囲の鍵に変更します.しかし、20210103と2012003の固有番号を持つ職員がいれば、03という値はハッシュ値を持つという問題が生じる.このような状況を衝突と呼ぶ.
挿入
最悪の場合はO(n)になる可能性があります.
削除
最悪の場合はO(n)になる可能性があります.
ブラウズ(Search)
最悪の場合はO(n)になる可能性があります.
ハッシュ競合
競合しない限り、ハッシュ・テーブルは、挿入、削除、およびブラウズの間、平均O(1)時間の複雑さを有する効率的なデータ構造である.
John SmithはSandra Deeのhashと同じです.これをHash Collisionと呼ぶ.ハトの巣の原理によれば、このような状況は必然的に現れる.
ハッシュ競合の解決方法
クローズドアドレッシングメソッド
Chaining
これは閉鎖アドレス法(closed addressing method)である.閉じたアドレスメソッドは、何が起こっても(衝突が発生しても)、自分の場所に保存されることを意味します.
これを可能にするには、価格を貯蔵するために複数の場所を手配するしかありません.複数の座席を手配する方法には、並べ替えの方法と接続リストの方法があります.
ただし、アレイが競合していない場合は、メモリが大量に消費され、競合の最大回数を決定する必要があるため、リストを使用してスロットを接続する方法は、閉じたアドレス方法を表します.
Sandra Deeの価格は153になります.もう価格があります.既存のJohn Smith値の後に接続します.
すなわち、フィルタリングは、データを格納する際に、リポジトリが競合した場合に、その値を既存の値に関連付ける方法である.
メモリが比較的少ないという利点がありますが、ハッシュ・テーブルのデータが接続され続けると(傾斜現象が発生すると)、検索効率が低下するという欠点があります.
in Java
HashMap vs HashTable
同期がサポートされているかどうかは異なります.
// 해시테이블의 put
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
addEntry(hash, key, value, index);
return null;
}
// 해시맵의 put
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
並列処理時にリソース同期を考慮する必要がある場合はハッシュテーブル(HashTable)を使用し、並列処理を行わない場合やリソース同期を考慮しない場合はハッシュテーブル(HashMap)を使用します.オープンアドレッシングメソッド
競合が発生した場合は、別の場所として保存します.ハッシュを探すルールによって,オープンアドレス方式は3つに分けられる.
1.線形調査法
これは、競合が発生した場合に、その隣の位置が空であるかどうかを確認し、空である場合にその位置に保存する方法です.隣の位置が空でない場合は、もう1つの格子を移動して位置を観察します.すなわち、f(k)+1->f(k)+2->f(k)+3.である.展開しかし,線形調査法の欠点は,衝突回数が増えるにつれてクラスタ現象が現れることである.
2.二次調査法
これは線形調査法の欠点を克服するために設計された方法である.衝突が発生した場合は、遠くから空き地を探す方法です.f(k)+1^2 -> f(k)+2^2 -> f(k)+3^2...順次展開する.
3.ツイストワイヤ
2回目の調査法でも、ハッシュ値が同じであれば、競合が発生したときに空のスロットを見つけるために、アクセス先が常に同じであるという問題があります.線形調査法よりは優れているが,近接しているスロットを中心にクラスタ現象が発生する確率は依然として高い.
二次調査法は遠くで空白を探していますが、空白を選ぶ方法は1マス、4マス、9マス…規則がある.このように不規則に空白空間を探す方法が二重ハッシュ法である.2つのハッシュ関数が書かれているので名前が付けられます.
比較
Reference
この問題について([リソース構造]TableとHash), 我々は、より多くの情報をここで見つけました https://velog.io/@humblechoi/자료구조-Table과-Hashテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol