Javascript数据结构与算法学习(五)——字典和散列表

字典

字典:是一种类似于集合的数据结构。 【集合:[值:值]对,字典:[键:值 ]对】

  • 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码取的值 可能 会一样,导致结果也是一样的,如下图:
解决冲突的折中方法:

  1. 分离链接:当取到的散列值相等时,在对应散列值处以链表的形式存储新进入的值
  2. 线性探查:当取到的散列值相等时,则向下一位未被占用的位置存储
    在这里插入图片描述
  • 分离链表法——解决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
}
发布了114 篇原创文章 · 获赞 146 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Sophie_U/article/details/103812700
今日推荐