JavaScript数据结构与算法04----哈希表的封装

今天上午封装了一下哈希表,逻辑倒是不怎么复杂,主要是理论知识,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>哈希表</title>
</head>
<body>
    <script>
        function HashTable() {
            this.storage = []
            this.count = 0
            this.limit = 8
            function hashFunc(str,limit) {
                var hashCode = 0;
                for(var i = 0; i < str.length; i++) {
                    hashCode = 37 * hashCode + str.charCodeAt(i)
                }
                var index = hashCode % limit
                return index
            }
            
            /*   错误取质数方法
            function getPrime(num) {
                var sqrtNum = Math.sqrt(num)
                for(var i = 2; i <= sqrtNum; i++) {
                    while (num % i == 0) {
                        num++
                    }
                }
            } 
            */

            //正确取质数方法
            function isPrime(num) {
                var sqrtNum = parseInt(Math.sqrt(num))
                for(var i = 2; i <= sqrtNum; i++) {
                    if(num % i == 0) {
                        return false
                    }
                }
                return true
            }

            function getPrime(num) {
                while(!isPrime(num)) {
                    num++
                }
                return num
            }
            HashTable.prototype.put = function(key,value) {
                var index = hashFunc(key,getPrime(this.limit))
                var bucket = this.storage[index]
                if(bucket == undefined) {
                    bucket = []
                    this.storage[index] = bucket
                }

                var isChange = false
                for(var i = 0; i < bucket.length; i++) {
                    var tuple = bucket[i]
                    if(tuple[0] == key) {
                        tuple[1] = value
                        isChange = true
                        break
                    } 
                }

                if(!isChange){
                    bucket.push([key,value])
                    this.count+=1
                    if(this.count >= this.limit * 0.75){
                        this.resize(getPrime(this.limit * 2))
                    }
                }  
            }

            HashTable.prototype.resize = function(newLimit) {
                var oldStorage = this.storage
                this.limit = newLimit
                this.count = 0
                this.storage = []

                oldStorage.forEach(function(bucket) {
                    if(bucket == null) {
                        return 
                    }

                    for(var i = 0; i < bucket.length; i++) {
                        var tuple = bucket[i]
                        this.put(tuple[0],tuple[1])
                    }
                }).bind(this)

            }

            HashTable.prototype.get = function(key) {
                var index = hashFunc(key,getPrime(this.limit))
                var bucket = this.storage[index]
                var hasFind = false
                if(bucket == undefined) {
                    return false
                }

                for(var i = 0; i < bucket.length; i++) {
                    var tuple = bucket[i]
                    if(tuple[0] == key) {
                        hasFind = true
                        return tuple[1]
                    } 
                }
                if(!hasFind) {
                    return false
                }
            }

            HashTable.prototype.remove = function(key) {
                var index = hashFunc(key,getPrime(this.limit))
                var bucket = this.storage[index]
                var isGet = this.get(key)
                if(!isGet){
                    return false
                }
                for(var i = 0; i < bucket.length; i++) {
                    var tuple = bucket[i]
                    if(tuple[0] == key) {
                        bucket.splice(i,1)
                        this.count-=1
                        if(this.limit > 7 && this.count < this.limit * 0.25) {
                            var primeNum = this.getPrime(Math.floor(this.limit / 2))
                            this.resize(primeNum)
                        }
                        break
                    } 
                }
            }

            HashTable.prototype.isEmpty = function() {
                return this.count == 0
            }

            HashTable.prototype.size = function() {
                return this.count
            }
        }

        var ht = new HashTable()
        ht.put('abc','123')
        ht.put('cba','321')
        ht.put('nba','521')
        ht.put('mba','520')
        console.log('ht',ht);
        console.log('getAbc',ht.get('abc'));
        console.log(ht.put('abc','111'));
        console.log('getAbc',ht.get('abc'));
        ht.remove('abc')
        console.log('getAbc',ht.get('abc'));
        console.log(ht.storage);
    </script>
</body>
</html>
 封装哈希表时出现的问题
 1.在封装获取质数的时候出现了问题,已经在源码中标注自己第一次封装质数时的错误
 代码逻辑,
 2.在封装哈希函数的时候,想不明白为什么`霍纳法则(秦九韶算法)`为什么会被转换
 成这样的算法,到现在也想不明白。
 3.在封装resize方法时,遇到了一个this指向问题,forEach中的this指向问题,看
 老师笔记才明白用forEach数组循环,为什么要加bind方法改变this指向,本以为会和
 react里面一样也可以用箭头函数轻松解决this指向问题,我天真了,用箭头函数
 去打印this,发现this指向还是window.
 4.封装remove方法的时候,少考虑当数量足够小的时候,需要降低哈希表的容量了。

你可能感兴趣的:(javascript,数据结构,算法,哈希表)