学习js数据结构与算法-散列表(1)

114 阅读3分钟

这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。

个人觉得要想进大厂,就必须学习了解算法和数据结构,经历了多次面试之后,也知道了算法和数据结构的重要性,所以,我也打算从今天开始,进入学习,下载了一下电子书,边看书,边跟着书的例子来敲一下代码,下面就开始总结一下对算法和数据结构的学习吧。

第二十三天:开始学习散列表

散列表

三列表也叫HashMap类,它是Dictionary类的一种散列表实现方式。

散列算法的作用是尽可能快的在数据结构中找到一个值,之前的数据结构获取值,需要迭代整个数据结构来找它。如果使用散列函数,就知道值的具体位置,因此能够快速的找到该值。

一个常见的应用就是使用散列表表示对象。js语言内部就是使用散列表来表示每个对象。

存储电子邮件地址簿,使用最常见的散列函数—lose lose 散列函数,,方法是简单地将每个键值中的每个字母ASCII值相加。

image.png

创建散列表

class HashTable {
  constructor(toStrFn = defaultToString) {
    this.toStrFn = toStrFn
    this.table = {}
  }
}

散列表的方法

  • put(key, value):向散列表增加一个新的项。

  • remove(key):根据键值从散列表中移除值。

  • get(key):返回根据键值检索到的特定的值。

在实现三个方法之前,需要实现散列函数

loseloseHashCaode(key) {
	if(typeof key === 'number') {
    return key
  }
  let tableKey = this.toStrFn(key)
  let hash = 0
  for(let i = 0; i < tableKey.length; i++) {
    hash += tableKey.charCodeAt(i)
  }
  return hash % 37
}
hashCode(key) {
  return this.loseloseHashCaode(key)
}

我们先判断key是不是数字类型,如果是,直接返回,如果不是数字类型,则用默认的toStrFn方法转换为一个字符串,然后循环这个字符串,用charCodeAt获取到每个字符串的ASCII值,相加起来,最后返回总值和一个任意数做出发的余数—这可以避免操作数超过数值变量最大表示范围的风险。

  • put(key, value)

    将键和值加入散列表中

    put(key, value) {
      if(value !== null) {
        const position = this.hashCode(key)
        this.table[position] = new ValuePair(key, value)
        return true
      }
    	return false
    }
    

    首先我们先检测传入的值是不是合法,如果不合法直接返回false, 如果合法,用hashCode找到位置,然后在table中添加ValuePair的实例,里面有原始的key和value值。

  • get(key)

    从散列表中获取一个值

    get(key) {
      const valuePair = this.table[this.hashCode(key)]
    	return valuePair === null ? undefined : valuePair
    }
    

    直接根据key获取table的值,如果值为null,则直接返回undefined,否则返回table对应key的值。

  • remove(key)

    从散列表中移除一个值

    remove(key) {
      const hash = this.hashCode(key)
      const valuePair = this.table[hash]
      if(valuePair !== null) {
        delete this.table[hash]
        return true
      } 
      return false
    }
    

    要移除一个值,我们需要先获取到当前key所在的位置,找到位置后,获取table在这个位置的值,如果该值为null,则代表没有,直接返回false,如果有,删除table的该位置。