Data Structureを整理してみましょう.//Part2
32616 ワード
Data Structure,
複数のデータセットの使用と格納方法を定義します.
3. Linked List
各ノードはリングの構造に接続されています.
音楽のプレイリストを考えればいいです.
リンクリストも音楽プレイリストと同様に、1つのノード(音楽)をループします.
ノードはdata(値)とnext(次のアドレスを指す)を有する.
*tailの場合はnext値はありません.
以下にLinked Listの基本的な方法を示します.
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
this.tail = null;
this._size = 0;
}
addToTail(value) {
//새로운 노드를 만든다.
let node = new Node(value);
//List가 비어있으면
//node를 추가하고 그 값을 head로 한다.
if(this.head === null) {
this.head = node;
this.tail = node;
this._size++;
} else {
//List가 비어있지 않다면
//head의 next값을 node에 추가하고
//그 값을 tail로 한다.
this.head.next = node;
this.tail = node;
this._size++;
}
return node;
}
remove(value) {
// linked list에서 주어진 value를 찾아 삭제
//1. linked list에 Node가 존재하지 않을 경우
//2. linked list에 Node가 존재 할 경우
//2-1. head의 value가 전달인자의 value랑 같은 경우
//2-2. 전달인자의 value값이 head에 없을 경우
if(this.head === null) {
return undefined;
}
if(this.head.value === value) {
this.head = this.head.next;
this._size--;
}
let current = this.head;
let _next = this.head.next;
while(_next) {
//삭제하고자 하는 value값이 head의 다음에 있다면
//head의 next를 value값이 있는 node 다음으로 연결
if(_next.value === value) {
current.next =_next.next;
this._size--;
//조건이 충족되면 break
break;
} else {
//그게 아니라면 한 칸씩 밀어서 다시 while문 작동
current = _next;
_next = _next.next;
}
}
}
getNodeAt(index) {
//주어진 index에 있는 값을 리턴
if(this._size < index) {
return undefined;
}
let current = this.head;
for(let i = 0; i < index; i++) {
current = current.next;
}
return current;
}
contains(value) {
//주어진 value가 포함되어있는지 확인
let current = this.head;
let _next = this.head.next;
while(_next) {
if(current.value === value) {
return true;
break;
} else {
current = _next;
_next = _next.next;
}
}
return false;
}
indexOf(value) {
//주어진 value값이 있는 node의 index 리턴
for (let i = 0; i < this._size; i++) {
let getNode = this.getNodeAt(i);
if (getNode.value === value) {
return i;
}
}
return -1;
}
size() {
return this._size;
}
}
4. Hash Table
Hash Tableは、割り当てられた空間にデータを格納する.
これらのデータはKeyとValueで受信されます.
Hash FunctionでHash Valueを受信し、指定した鍵を保存する場所に保存します.
*オブジェクトと似ていますが、オブジェクトとは異なり、構造化されたHash ValueがHash Functionによって得られます.
これはHashingと言います.
*韓興はデータ管理が必要です.
異なる長さのデータを固定形式のデータにマッピングする操作.
それを実現する関数をHash Functionと呼ぶ.
下図を見てください.
10番のHash Tableがございます
「福崇:チャール」という名前のkey-valuepair
Hash Functionで1というHash Valueを獲得しました.
Hash Tableの1にvalueを格納します.
残りのkey-value pairもそうです.
Hash Tableの致命的な欠点は、Hash Collision(衝突)が発生する可能性があることです.
異なるkey-valuepairがあっても、同じハッシュ値が現れる可能性があるので、競合を処理する方法を考えなければなりません.
次はHash Tableの基本的な方法です
LimitedArrayとHashFunctionはさらに説明する必要があるかもしれません.
コードの大まかな流れを理解すればよい.
class HashTable {
constructor() {
this._size = 0;
this._limit = 8;
this._storage = LimitedArray(this._limit); // 객체의 형태
}
//삽입: 주어진 key와 value를 해시함수의 결과값 인덱스의 bucket에 저장한다. bucket은 linkedlist, [key, value] 쌍은 Node 형태로 저장 {key: key, value: value, next: ~ }
insert(key, value) {
//insert 할 때 resizie
//size를 limit로 나눈 값이 75%이상이면 limit를 두배로 늘린다.
if(this._size / this._limit >= 0.75) {
this._resize(this._limit * 2);
}
const index = hashFunction(key, this._limit);
//index값에 접근할 수 있는 변수 설정
let bucket = this._storage.get(index);
let tuple = [key, value];
//bucket에 데이터가 없을 경우, set 메소드로 추가.
if(bucket === undefined) {
this._storage.set(index, [tuple])
}
//bucket에 데이터가 있을 경우,
// 1. key가 같을 경우, 기존 value값을 덮어쓴다.
// 2. key가 다를 경우, bucket 안에 linked list에 추가.
else {
for(let i = 0; i < bucket.length; i++) {
if(bucket[i][0] === key) {
bucket[i][1] = value;
} else {
bucket.push(tuple);
}
}
}
//추가할 때 마다 사이즈 증가.
this._size++;
}
// 탐색: 원하는 key에 해당하는 value를 찾는 연산
retrieve(key) {
//주어진 키에 해당하는 값을 반환합니다. 없다면 undefined를 반환합니다.
const index = hashFunction(key, this._limit);
let bucket = this._storage.get(index)
let result;
//key가 주어지면 value를 리턴.
//주어진 key에 value가 없으면 undefined.
// 있으면 value 리턴.
if(bucket === undefined) {
return undefined;
} else {
for(let i = 0; i < bucket.length; i++) {
if(bucket[i][0] === key) {
result = bucket[i][1]
}
}
}
return result;
}
remove(key) {
if(this._size / this._limit <= 0.25) {
this._resize(this._limit / 2);
}
const index = hashFunction(key, this._limit);
let bucket = this._storage.get(index)
let result = undefined;
for(let i = 0; i < bucket.length; i++) {
if(bucket[i][0] === key) {
result = bucket[i][1];
bucket.splice(i, 1);
this._size--;
}
}
return result;
}
_resize(newLimit) {
let current_storage = this._storage;
this._limit = newLimit;
this._size = 0;
this._storage = LimitedArray(newLimit);
current_storage.each(bucket => {
if(bucket) {
for(let i = 0; i < bucket.length; i++) {
this.insert(bucket[i][0], bucket[i][1]);
}
}
})
}
}
Reference
この問題について(Data Structureを整理してみましょう.//Part2), 我々は、より多くの情報をここで見つけました https://velog.io/@900djob/Data-Structure를-정리해보자.-Part2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol