HashTable

HashTable은 key에 Value를 저장하는 데이터 구조로 get(key)의 동작이 O(1)의 시간복잡도로 수행된다.

동작방식은 key를 hashing(hashFunction(key) % bucketSize)해서 index값을 구하고 내부의 array의 index에 value를 저장한다.

이런 형식으로 data를 저장하면, key에 대한 data를 찾을때, hashing 한번만 수행하면 array내에 저장된 index 위치를 찾아낼 수 있기 때문에, data 저장과 삭제가 빠르다(O(1)).

하지만 hashFunction(key) / bucketSize 값이 중복이 될수가 있기때문에 Linked-list를 사용하거나 array를 사용해서 충돌을 해결할 수 있다.

class HashTable {
  constructor(bucketSize = 1024) {
    this._bucketSize = bucketSize
    this._data = new Array(bucketSize)
  }

  getHashKey(key) {
    const h = key
      .split('')
      .reduce((acc, cur, i) => acc + cur.charCodeAt(0) * (i + 1), 0)
    return h % this._bucketSize
  }

  set(key, value) {
    if (typeof key !== 'string') {
      key = JSON.stringify(key)
    }
    const hashKey = this.getHashKey(key)
    const bucket = this._data[hashKey]
    if (!bucket) {
      return (this._data[hashKey] = [[key, value]])
    }
    const idx = bucket.findIndex(([storedKey]) => key === storedKey)
    if (idx === -1) {
      return bucket.push([key, value])
    }
    bucket[idx][1] = value
  }

  get(key) {
    if (typeof key !== 'string') {
      key = JSON.stringify(key)
    }
    const bucket = this._data[this.getHashKey(key)]
    if (bucket) {
      const data = bucket.find(([storedKey]) => key === storedKey)
      return data ? data[1] : undefined
    }
    return undefined
  }
}

const ht = new HashTable()
ht.set({ x: 210 * 2 }, 420)
ht.set({ x: 210 * 2 }, 1)
ht.set([1, 2, 3], 2)
ht.set('cba', 3)

ht.get({ x: 420 }) // 1
ht.get([2, 4, 6].map(x => x / 2)) // 2
ht.get('cba') // 3

Last updated