js哈希存储容器 (自写)

简单js哈希存储容器:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>自作哈希存储容器</title>
</head>
<body>
  <h1>见控制台打印</h1>
  <script>
    //自作哈希存储链表存储容器
    let HashTable = (function () {
      //避免外部访问
      let symbol = Symbol();

      //用于哈希表的链表
      let LinkedList = (function () {
        //避免外部访问
        let HEAD = Symbol();
        //存储数据与next节点的类
        class Node {
          constructor(data) {
            this.data = data;   //存储数据
            this.next = null;   //指向下一节点
          }
        }

        return class {
          constructor() {
            //数据链头
            this[HEAD] = null;
          }
          //尾部追加数据
          append(data) {
            //创建对应的链节点
            let node = new Node(data);
            //获取链头
            let head = this[HEAD];
            //如果是链头 则null
            if (head === null) {
              this[HEAD] = node;
              return;
            } else { //如果不是链头
              //如果不是链头  循环找到链尾
              while (true) {
                //如果key相等说明值存在,需修改值
                if (head.data.key === data.key){
                  head.data.value = data.value;
                  return true;  //添加后return
                }
                if(head.next !== null){
                  //循环得到最后一个有值的next
                 head = head.next;
                }else{
                  break;
                }
              }
              //把最后一个next=null 赋值给新添加node
              head.next = node;
            }
          }
          //取值
          find(index) {
            let head = this[HEAD];
            let i = 0;
            while (head) {
              if (i === index) return head;
              head = head.next;
              i++;
            }
            //超出长度返回null
            return null;
          }
          //移除
          remove(index) {
            //当前index后面对应的node数据链
            let nodeBefore,
              nodeAfter = this.find(index + 1);

            //考虑index=0的情况
            if (index === 0) {
              //直接等于0后面的数据
              this[HEAD] = nodeAfter;
            } else {
              //获取前一个数据 从而插入到前一个数据后面
              nodeBefore = this.find(index - 1);
              nodeBefore.next = nodeAfter;
            }
          }
          //返回头
          getHead(){
            return this[HEAD];
          }
          //长度
          size() {
            let i = 0,
              head = this[HEAD];
            while (head) {
              head = head.next;
              i++;
            }
            return i;
          }
        }
      })();

      //哈希函数
      function HASH(key) {
        let hash = 0;
        //通过key值获取每个字母唯一的Unicode码并累加
        [...key].forEach(s => {
          hash += s.charCodeAt(0);
        })
        //取模这样可以解决重复占用大问题
        return hash % 37;
      }

      //用于链表存储的类
      class ValuePair {
        constructor(key, value) {
          this.key = key;
          this.value = value;
        }
      }

      return class {
        constructor() {
          this[symbol] = [];
        }
        set(key, value) {
          let hash = HASH(key),
                 H = hash; //存储初始位置
          //判断该哈希是否已经存值 得到没有存值的hash
          while(this[symbol][hash]){
            //判断是否以有key值 有则修改value的值
            if(key === this[symbol][hash].key){
              this[symbol][hash].value = value;
              return true;
            }
            hash ++;  //这是以经过HASH的值
            hash % 37;
            //相等证明循环到原位
            if(hash === H){
              throw new Error('哈希表已满');
            }
          }
          this[symbol][hash] = new ValuePair(key,value);
          return true;
        }
        get(key) {
          let hash = HASH(key),
                 H = hash; //存储初始位置
          if(!this[symbol][hash])return undefined;
          while(this[symbol][hash]){
            if(this[symbol][hash].key === key){
              return this[symbol][hash].value;
            }
            hash++;
            hash %= 37;
            //相等证明循环到原位
            if(hash === H){
              return undefined;
            }
          }
          //当向下查询时有一项为空就说明没有存此值
          return undefined;
        }
      }
    })();

    let hash = new HashTable;
    hash.set('小米', "男");
    hash.set('奇奇', "女");
    hash.set('派大星', "男");
    hash.set('海绵宝宝', "女");

    console.log(hash);
    hash.set('海绵宝宝', "男");
    console.log(hash);
    hash.set('宝宝海绵', "111");
    console.log(hash.get('宝宝海绵'));	//111

  </script>
</body>
</html>

运行结果如下:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值