字典
字典:是一种类似于集合的数据结构。 【集合:
[值:值]
对,字典:[键:值 ]
对】
- JS数据类型对象就是字典的一种实现
- ES6中的Map,WeakMap也是一种字典的实现
字典的主要操作
- 添加键值对:set(key,value)
- 通过键值移除元素:delete(key)
- 检查键:has(key)
- 由键获取值: get(key)
- 获取字典的所有值 : values
- 获取字典的所有键:keys
function Dictionary (){
var items ={}
this.has = function(key){
return key in items
}
this.set = function(key,value){
items[key] = value
}
this.delete = function(key){
if(this.has(key)){
delete items[key]
return true
}
return false
}
this.values = function(){
let res = []
for(let key in items){
if(items.hasOwnProperty(key)){
res.push(items[key])
}
}
return res
// 方法二: return Object.values(items)
}
this.keys = function(){
return Object.keys(items)
}
this.get = function(key){
return itmes[key]
}
}
散列表(哈希表)
如上图,例将Jobs拆分为
J,o,b,s
四个字母,再通过ASCII码中对应字码的值,74,111,98,115
相加后得到一个值 398作为键,对应值即要存储的内容。这是一种简单的存储方式,关键点在于散列函数
(用于生成键),常用的散列函数有loselosehashcode ,
- 散列表VS其他数据结构
散列表可以快速定位元素,而其他数据结构获取值时需要遍历元素
散列函数
- loseloseHashCode
原理:以key的每项ASCII码值相加得到的结果,对37取余后的值作为key,来存储对应值
// 散列函数一
var loseloseHashCode = function (key){
var hash = 0
for(var i=0;i<key.length;i++){
hash += key[i].charCodeAt()
}
return hash % 37; //公认规则 取余37
}
- loseloseHashCode的缺陷
由于loseloseHashCode通过ASCII码取的值 可能 会一样,导致结果也是一样的,如下图:
解决冲突的折中方法:
- 分离链接:当取到的散列值相等时,在对应散列值处以链表的形式存储新进入的值
- 线性探查:当取到的散列值相等时,则向下一位未被占用的位置存储
- 分离链表法——解决hash冲突
var LinkedList = function(){
// 链表头
var head = null
// 链表长度
var length = 0
// 辅助类
var Node = function(elem){
this.elem = elem
this.next = null
}
// 添加元素
this.append = function(el){
var node = new Node(el)
if(head===null){
head = node
}else{
var current= head;
while(current.next){
current = current.next
}
current.next=node
}
length ++;
}
// 插入
this.insert = function(position,element){
var current = head
var node = new Node(element)
if(position===0){
head = element
head.next = current
}else{
var index = 0
var previous= null
while(index<position){
previous = current
current = current.next
index++
}
previous.next = node
node.next = current
}
length ++
}
// 删除
this.removeAt = function(position){
if(position>-1&&position<length){
// 删除首位
if(position===0){
var current = head
head = current.next
}else{
// 删除其他位置
var previous = null
var current = head
var index = 0
while(index<position){
previous=current
current = current.next
index++
}
// 跳出循环时,index === position
previous.next = current.next
}
}
length --;
return current
}
// 获取元素位置
this.indexOf = function (ele){
var index =0
var current = head
while(current){
if(ele === current.elem){
return index
}
index ++
current = current.next
}
return -1
}
this.remove = function(elem){
return this.removeAt(this.indexOf(elem))
}
this.isEmpty = function(){
return length ===0
}
this.size = function(){
return length
}
this.printHead = function(){
return head
}
}
function HashTable_L(){
var table = []
// 散列函数一
var loseloseHashCode = function (key){
var hash = 0
for(var i=0;i<key.length;i++){
hash += key[i].charCodeAt()
}
return hash % 37; //公认规则 取余37
}
// 辅助类
var Node = function(key,value){
this.key = key
this.value = value
}
this.put = function(key,value){
var position = loseloseHashCode(key)
if(!table[position]){
var l = new LinkedList
table[position] = l
}
table[position].append(new Node(key,value))
}
// 获取值
this.get = function(){
var position = loseloseHashCode(key)
if(table[position]){
var current = table[position].getHead()
while(current){
if(current.elem.key == key){
return current.elem.value
}
current = current.next
}
}else{
return undefined
}
}
// 删除值
this.remove = function (){
var position = loseloseHashCode(key)
if(table[position]){
var current = table[position].getHead()
while(current){
if(current.elem.key===key){
table[position].remove(current.element)
if(table[position].isEmpty()){
table[position]=undefined; //内存空间设置为原始值,减少性能开销
}
return true
}
current = current.next
}
}else{
return false
}
}
this.get = function(key){
return table
}
}
var hashTable= new HashTable_L()
hashTable.put('Donnie','[email protected]')
hashTable.put('Ana','[email protected]')
hashTable.get()[13].printHead()
- djb2HashCode
function djb2HashCode(key){
var hash = 5381
for(var i=0;i<key.length;i++){
hash = hash * 33 + key[i].charCodeAt()
}
return hash % 1013
}