JavaScript解决散列表的冲突(线性探查法)
线性探查:当想表中的某个位置添加一个元素的时候,如果索引为position的位置已经被占据了,就尝试position+1的位置。如果position的位置也被占据了,就尝试position+2的位置,以此类推,直到在散列表中找到一个空闲的位置。
put(key, value) { if (key != null || value != null) { let position = hashCode(key); //获取散列函数生成的位置 if (this.table[position] != null) { //如果位置上为空 this.table[position] = new ValuePair(key, value); //将元素添加在位置上 } else { let index = position + 1; //如果位置上没空,就向下寻找下一个空位置 while (this.table[index] != null) { index++; } this.table[index] = new ValuePair(key, value); //将元素添加到空位置上 } return true; } return false; } get(key) { let position = hashCode(key); //通过散列函数找到位置 if (this.table[position] != null && this.table[position].key === key) { return this.table[position].value; //如果位置正好是要找的值 } let index = position + 1; //从位置开始遍历到散列表,找到键所在的键值对或null while (this.table[index] != null && this.table[position].key !== key) { index++; } if (this.table[index] != null && this.table[index].key === key) { //如果不为null就是所找位置 return this.table[index].value; } return undefined; //没找到返回undefined } verifyRemoveSideEffect(key, removedPosition) { //验证是否有副作用 const hash = this.hashCode(key); let index = removedPosition + 1; //position是索引值 while (this.table[index] != null) { //如果下面有元素 let posHash = this.hashCode(this.table[index].key); //判断是不是之前向下移的元素 if (posHash <= hash || posHash <= removedPosition) { //散列值是否小于索引值或删除键的散列值 this.table[removedPosition] = this.table[index]; //把之前的 delete this.table[index]; removedPosition = index; } index++; //一个一个元素向下查找,直到下一个元素是null } } remove(key) { const position = this.hashCode(key); //散列值 if (this.table[position] != null && this.table[position].key === key) { delete this.table[position]; //散列值位置上正好是key所在对象 this.verifyRemoveSideEffect(key, position); //删除后把应该上移的元素上移 return true; } let index = position + 1; while (this.table[index] != null && this.table[index].key !== key) { index++; } if (this.table[index] != null && this.table[index].key === key) { delete this.table[index]; this.verifyRemoveSideEffect(key, index); return true; } return false; }