数据结构-集合、字典、散列

123 阅读1分钟

集合

集合是一种存储不重复数据的结构,es5中set是具体实现

集合实现


 class Set {
     item = {};

    add(key) {
      if (!this.has(key)) {
        this.item[key] = key
        return true
      }

      return false
    }

    remove(key) {
      if (this.has(key)) {
        delete this.item[key]
        return true
      }

      return false
    }

    // 并集
    union(otherSet = {}) {
      const newSet = new Dictionary()

      this.values().forEach((item) => newSet.add(item))
      otherSet.values().forEach((item) => newSet.add(item))

      return newSet.values()
    }

    // 交集
    intersect(otherSet = {}) {
      return this.values().filter((item) => otherSet.has(item))
    }

    // 差集
    subtract(otherSet = {}) {
      return this.values().filter((item) => !otherSet.has(item))
    }

    values() {
      const values = []
      for (const key in this.item) {
        if (this.has(key)) {
          values.push(this.item[key])
        }
      }

      return values
    }

    has(key) {
      return Object.prototype.hasOwnProperty.call(this.item, key)
    }

    size() {
      let i = 0
      for (const key in this.item) {
        if (this.has(key)) {
          i++
        }
      }

      return i
    }

    clear() {
      this.item = {}
    }
  }

字典

使用[key, value]来存储数据,其中key值类型不限, es6中map是具体实现

字典具体实现



 const toStringFn = (key) => {
    if (key === null) {
      return 'NULL'
    }

    if (key === undefined) {
      return 'UNDEFINED'
    }

    if (typeof key === 'string') {
      return `${key}`
    }

    return Object.prototype.toString.call(key)
  }

  // 保存原来key, value
  class ValueMap {
    constructor(key, value) {
      this.key = key
      this.value = value
    }

    toString() {
      return `${this.key}:${this.value}`
    }
  }

  class Dictionary {
    item = {}

    add(key, value) {
      if (!key || !value) {
        return false
      }

      const transformKey = toStringFn(key)
      this.item[transformKey] = new ValueMap(key, value)

      return true
    }

    remove(key) {
      if (this.has(key)) {
        delete this.item[key]
        return true
      }

      return false
    }

    has(key) {
      return Object.prototype.hasOwnProperty.call(this.item, toStringFn(key))
    }

    keys() {
      const keys = []
      for (const key in this.item) {
        if (this.has(key)) {
          keys.push(this.item[key].key)
        }
      }

      return keys
    }

    values() {
      const values = []
      for (const key in this.item) {
        if (this.has(key)) {
          values.push(this.item[key].value)
        }
      }

      return values
    }

    size() {
      return this.keys().length
    }

    clear() {
      this.item = {}
    }
  }


散列表

散列算法是尽可能快的在数据结构中查找元素,在栈、队列、字段章节中,查找元素需要遍历元素的,对于数据量大并且目标元素在数据末尾,查找效率低下,费时

散列表算法

  • 分离链接: 使用链表 将 key 编码之后,value 存放在 key 对应的链表上
  • 线性侦查: 判断当前 key 是否存在,不存在就以当前 key 作为索引存储,如果存在,则继续寻找 index+1 为空的位置,存储 key-valu
  • 高性能散列算法

  class HashTable {
    item = {}

    djbHashTable(key = '') {
      let hash = 5381 // 素数
      for (let i = 0; i < key.length; i++) {
        hash = hash * 33 + key.charCodeAt(i)
      }

      return hash % 1013 // 数据
    }

    put(key, value) {
      const hash = this.djbHashTable(key)
      this.item[hash] = value
    }

    get(key) {
      return this.item[this.djbHashTable(key)]
    }

    remove(key) {
      delete this.item[this.djbHashTable(key)]
    }

    size() {
      console.log('run size')
      return Object.keys(this.item).length
    }

    print() {
      const keys = Object.keys(this.item)
      let str = ''
      for (let i = 0; i < keys.length; i++) {
        str += `key: ${keys[i]}: value:${this.item[keys[i]]}\n`
      }

      console.log(str)
    }
  }