七、散列表
1、名称解释:散列算法的作用是尽可能快地在数据结构中找到一个值。给定一个键值,返回相应值在表中的地址。
2、散列表基本功能:
- 添加新项:put(key, vlaue)
- 移除相应项: remove(key)
- 返回根据键值检索到特定的值: get(key)
3、“lose lose”散列函数的基本结构:
- 名词解释:简单的将每个键值中的每个字母的ASCII值相加。
- 基本框架:
function HashTable() { var table = [] var loseloseHashCode = function (key) { var hash = 0 for (let i = 0; i < key.length; i++) { hash += key.charCodeAt(i) } return hash % 37 } }
- 添加键值对:
this.put = function (key, value) { var position = loseloseHashCode(key) table[position] = value; }
- 移除键值对:
this.remove = function (key) { table[loseloseHashCode(key)] = undefined }
- 返回特定的值:
this.get = function (key) { return table[loseloseHashCode(key)] }
4、分离链接优化散列表:
- 名词解释: 分离链接法包括为散列表的每个位置创建一个链表并将元素存储在里面。它是解决冲突的最简单的方法,但是它在HashTable实例之外还需要额外的存储空间。
- 基本框架的优化:
var loseloseHashCode = function (key) { var hash = 0 for (let i = 0; i < key.length; i++) { hash += key.charCodeAt(i) } return hash % 37 } var ValuePair = function (key, value) { this.key = key; this.value = value; this.toString = function () { return '[' + this.key + '-' + this.value + ']' } }
-
put方法优化:
this.put = function (key, value) { var position = loseloseHashCode(key) if(table[position]==undefined){ table[position] = new LinkedList() } table[position].append(new ValuePair(key, value)) }
-
get方法优化:
this.get = function (key) { var position = loseloseHashCode(key) if(table[position]!==undefined){ var current = table[position].getHead(); while(current.next){ if(current.element.key === key){ return current.element.value } current = current.next } if(current.element.key === key){ return current.element.value } } return undefined }
-
remove方法优化:
this.remove = function (key) { var position = loseloseHashCode(key) if(table[position]!==undefined){ var current = table[position].getHead() while(current.next){ if(current.element.key === key){ table[position].remove(current.element) if(table[position].isempty()){ table[position] = undefined; } return true } current = current.next; } if(current.element.key === key){ table[position].remove(current.element) if(table[position].isempty()){ table[position] = undefined } return true } } return false }
5、线性探查优化散列表:
- 名词解释:当想向表中某个位置加入一个新元素的时候,如果索引为index的位置已经被占据了,就尝试index + 1的位置。依次类推。
- put代码优化:
this.put = function (key, value) { var position = loseloseHashCode(key) if(table[position]==undefined){ table[position] = new ValuePair(key, value) }else{ var index = ++position; while(table[index]!= undefined){ index++ } table[index]= new ValuePair(key, value) } }
-
get方法优化:
this.get = function (key) { var position = loseloseHashCode(key) if(table[position]!==undefined){ if(table[position].key === key){ return table[position].value }else{ var index = ++position; while(talbe[index]===undefined || table[index].key !== key){ index++ } if(table[index].key === key){ return table[index].value } } } return undefined }
- remove方法优化:
this.remove = function (key) { var position = loseloseHashCode(key) if(table[position]!==undefined){ if(table[position].key === key){ return table[index] = undefined }else{ var index = ++position; while(talbe[index]===undefined || table[index].key !== key){ index++ } if(table[index].key === key){ return table[index] = undefined } } } return undefined }
6、“djb2”散列函数:
- 优化loseloseHashCode函数:
var djb2HashCode = function (key) { var hash = 5381 for (let i = 0; i < key.length; i++) { hash = hash * 33 + key.charCodeAt(i) } return hash % 1013 }
7、ES6——Map类
- 相应的代码:
var map = new Map() //新建字典 map.set(key, value) //添加键值对 map.has(key) //通过键名判断字典中是否存在键值对 map.size //输出字典键值对个数 map.keys() //输出所有的键名 map.values() //输出所有的值 map.get(key) //输出相应的值
map.delete(key) //删除相应的键值对
map.clear() //重置map数据结构
8、ES6——WeakMap类和WeakSet类
- 弱化版本与原版本区别:
- weakMap与WeabSet类没有entries、keys、和values等方法。
- 只能用对象作为键。
- 弱化版本的优点:
- WeakSet和WeakMap是弱化的(用对象作为键),没有强引用的键。这使得JavaScript的垃圾回收器可以从中清除整个入口。
- 必须用键才可以取出值。这些类没有entries、keys和values等迭代器方法,因此,除非你知道键,否则没有办法取出值。