データ構造05ハッシュテーブル|JS
18105 ワード
Hash Table
Hash Table: Hash collision resolved by seperate chaining
画像ソース
固定長データにマッピングして効率的なデータ管理 ハッシュ関数を実装することによってデータ値をハッシュ値 にマッピングする
hashcode:ハッシュ関数によって返されるデータの一意の数値(キー値) hashcode快速検索データ より少ないリソースでより多くのデータを管理
:限定されたハッシュ値(HDD、クラウドなど)に無限のデータをマッピングすることによって管理 不自然なhash関数でキー値を決定すると、同じ値 を導出することができる同じキー値は、複数のデータが1つのテーブルで競合していることを示します Collision:2つの異なるキーが同じインデックスを使用してハッシュされる(hash関数による計算を示す) 一般的に、良いhash関数は、鍵の一部を参照してハッシュ値を作成するのではなく、鍵全体を参照してハッシュ値を作成する.しかし、良いハッシュ関数は、キーがどのような特性を有するかに依存する. hash関数を1:1に無条件に設定するよりも、衝突を最小化する方向にどのように設計し、発生した衝突に対応するかが重要である.1:1の対応は難しいが、このようなhash関数を作成するのはarrayと変わらず、メモリが多すぎる. Collisionが多ければ多いほど,探索に要する時間的複雑さはO(1)からO(n)に近づく.熟練していないhash関数はhashをhashのように使用することを許さない.良いhash関数を選択することは、hashテーブルのパフォーマンスを向上させるために必要です.
HASH競合時に他のHASHパケットにデータを挿入する方法 切寧:接続リストにノードを追加し続ける(制限なく接続を継続するがメモリの問題) 接続リストの使用各bucketを接続リスト(リンクリスト)として作成し、競合が発生したときにbucketのリスト に追加する方法接続リストの特徴を継承し、削除や挿入は簡単であるが、欠点は依然として存在するため、小さなデータを格納する際、接続リスト自体のオーバーヘッドが大きい.データ量が小さい場合は、リンクリスト を使用することが望ましい.
ツリーの使用方法Treeの基本アルゴリズムは、接続リストではなくツリーを使用してSeparate Chainingと同じです ハッシュ・パケット数が少ない場合はメモリを節約できますが、ハッシュ競合によるパフォーマンス損失 key-value対データ数が一定数(75%)を超えると、ハッシュパケット数が2倍になる
Github | tech-interview-for-developer
Github | Interview_Question_for_Beginner
Github | javascript-algorithms | trekhleb
Photo by Alain Pham on Unsplash
Hash Table: Hash collision resolved by seperate chaining
画像ソース
ハッシュ表|HashTable
ハッシュ関数
:限定されたハッシュ値(HDD、クラウドなど)に無限のデータをマッピングすることによって管理
衝突(衝突)
良いハッシュ関数の条件
競合の解決
オープンアドレスほう
「分離式」(Separate Chaining)|「分離式」(Chaining)
ツリーの使用方法
ハッシュ・パケットの動的拡張(Resize)
接続リストによる実装
import LinkedList from '../linked-list/LinkedList';
const defaultHashTableSize = 32;
export default class HashTable {
constructor(hashTableSize = defaultHashTableSize) {
// 해시 테이블을 만들고 각 버킷을 빈 연결 리스트로 채움
this.buckets = Array(hashTableSize).fill(null).map(() => new LinkedList());
this.keys = {};
}
// 해시 함수: key 문자열을 해시 번호로 변환
hash(key) {
// 단순화 하기 위해 키의 모든 문자의 문자 코드 합계를 사용하여 해시를 계산합니다.
// 그러나 충돌 횟수를 줄이기 위해 다항식 문자열 해시와 같은 보다 정교한 방식을 사용할 수도 있습니다.
// hash = charCodeAt(0) * PRIME^(n-1) + charCodeAt(1) * PRIME^(n-2) + ... +
// charCodeAt(n-1) 여기서 charCodeAt(i)는 키의 i번째 문자 코드이고
// n은 키의 길이이며 PRIME은 31과 같은 임의의 소수입니다.
const hash = Array.from(key).reduce((hashAccumulator, keySymbol) => {
hashAccumulator + keySymbol.charCodeAt(0)
}, 0);
// 해시 테이블 크기에 맞도록 해시 수를 줄입니다.
return hash % this.buckets.length;
}
set(key, value) {
const keyHash = this.hash(key); // 해시 코드
this.keys[key] = keyHash; // 해시코드를 keys 객체에 저장
// 버킷에서 해시코드에 해당하는 연결 리스트를 가져옴
const bucketLinkedList = this.buckets[keyHash];
// 버킷연결리스트에서 동일한 키를 가진 노드가 있는지 탐색
const node =
bucketLinkedList.find(
{ callback: (nodeValue) => nodeValue.key === key }
);
if (!node) {
// 동일한 키를 가진 노드가 없다면 새 노드를 삽입
bucketLinkedList.append({ key, value });
} else {
// 동일한 키를 가진 노드가 있다면 값 업데이트
node.value.value = value;
}
}
delete(key) {
const keyHash = this.hash(key); // 해시 코드
delete this.keys[key]; //
const bucketLinkedList = this.buckets[keyHash];
const node = bucketLinkedList.find(
{ callback: (nodeValue) => nodeValue.key === key }
);
if (node) {
return bucketLinkedList.delete(node.value);
}
return null;
}
get(key) {
const bucketLinkedList = this.buckets[this.hash(key)];
const node = bucketLinkedList.find(
{ callback: (nodeValue) => nodeValue.key === key }
);
return node ? node.value.value : undefined;
}
has(key) {
return Object.hasOwnProperty.call(this.keys, key);
}
getKeys() {
return Object.keys(this.keys);
}
getValues() {
return this.buckets.reduce((values, bucket) => {
const bucketValues = bucket.toArray()
.map((linkedListNode) => linkedListNode.value.value);
return values.concat(bucketValues);
}, []);
}
}
📚 リファレンス
Github | tech-interview-for-developer
Github | Interview_Question_for_Beginner
Github | javascript-algorithms | trekhleb
Photo by Alain Pham on Unsplash
Reference
この問題について(データ構造05ハッシュテーブル|JS), 我々は、より多くの情報をここで見つけました https://velog.io/@protect-me/자료구조-05-해시테이블-JSテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol