Javascript中的字典和散列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
function Dictionary() {
  var items={};
  this.set=function (key,value) {
    items[key]=value;
  };
  this.remove=function (key) {
    if(this.has(key)){
      delete items[key];
      return true;
    }
    return false;
  };
  this.has=function (key) {
    return key in items;
  };
  this.get=function(key){
    return this.has(key)?items[key]:undefined;
  };
  this.clear=function(){
 
  };
  this.size=function(){
 
  };
  this.keys=function () {
 
  };
  this.values=function () {
    var values=[];
    for (var k in items) {
      if (this.has(k)) {
        values.push(items[k]);
      }
    }
    return values;
  };
  this.getItems=function(){
    return items;
  };
 
}
// 解决散列值重复的三种方法:分离链接、线性探查、双散列法。
// 1、分离链接法为散列表的每一个位置创建一个链表并将元素存储在里面
//分离链接的哈希表
//被注释的为普通的哈希表
function HashTable() {
  var table=[];
  var loseHashCode=function(key){
    var hash=0;
    for(var 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+"]";
    }
  }
  this.put=function(key,value){
    var position=loseHashCode(key);
    // console.log(position,"-",key);
    // table[position]=value;
    if(table[position]==undefined){
      //每一个位置都是一个链表
      table[position]=new LinkedList();
    }
    table[position].append(new ValuePair(key,value));
  };
  this.remove=function(key){
    //table[loseHashCode(key)]=undefined;
    var position=loseHashCode(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(element);
        if(table[position].isEmpty()){
          table[position]=undefined;
        }
        return true;
      }
    }
    return false;
  };
  this.get=function(key){
    //return table[loseHashCode(key)];
    var position=loseHashCode(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;
  };
  this.print=function(){
    for (var i = 0; i < table.length; i++) {
      if(table[i]!=undefined){
        console.log(i,":",table[i]);
      }
    }
  };
}
//2、线性探查
// 当想向表中某个位置加入一个新的元素时,如果索引为index的位置已经被占据了,
// 就尝试index+1的位置。如果index+1的位置也被占据了,就尝试index+2的位置
// 以此类推
function LDHashTable() {
  // ... 省略重复的代码
  this.put=function (key,value) {
    if(table[position]==undefined){
      table[position]=new KeyValuePair(key,value);
    }else{
      var index=++position;
      while (table[index]!=undefined) {
        index++
      }
      table[position]=new KeyValuePair(key,value);
    }
  }
  this.get=function (key) {
    var position=loseHashCode(key);
    if(table[position]!==undefined){
      if(table[position].key===key){
        return table[position].value;
      }else{
        var index=++index;
        // 原书中是 table[index]===undefined || table[index].key!==key
        while (table[index]!==undefined && table[index].key!==key) {
          index++;
        }
        if(table[index] && table[index].key===key){
          return table[index].value;
        }
      }
    }
  }
}
 
// 更好的散列函数
var djb2HashCode=function (key) {
  var hash=5381;//一个质数,大多数情况下为5381
  for (var i = 0; i < key.length; i++) {
    hash=hash*33+key.charCodeAt(i);
  }
  return hash%1013;//1013为比散列表大小要大的一个质数
}

  

posted @   白不菜  阅读(434)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示