字典
字典是一种以键-值对模式存储数据的数据结构,JavaScript的Object类就是以字典的模式设计的。上面用代码实现字典类以及相干操作方法
Dictionary类
datastore为数据集
class Dictionary{
datastore=[]
constructor(){
}
}
add()增加键值对
add(key, value) {
this.datastore[key]=value
}
get()失去键的值
get(key) {
return this.datastore[key]
}
remove()移除元素
remove(key) {
delete this.datastore[key]
}
showAll()打印全副信息
showAll() {
for(let key in this.datastore){
console.log(`key=>${this.datastore[key]}`)
}
}
clear()清空操作
clear() {
for(let key in this.datastore){
delete this.datastore[key]
}
}
残缺代码
class Dictionary {
datastore = []
constructor() {
}
add(key, value) {
this.datastore[key] = value
}
find(key) {
return this.datastore[key]
}
remove(key) {
delete this.datastore[key]
}
showAll() {
for (let key in this.datastore) {
console.log(`key=>${this.datastore[key]}`)
}
}
count() {
let num = 0
for (let key in this.datastore) {
num++
}
return num
}
clear() {
for (let key in this.datastore) {
delete this.datastore[key]
}
}
}
散列
散列是一种罕用的数据存储技术,散列后的数据能够疾速地插入或取用。散列应用的数据结构叫做散列表。
整个散列过程其实就是两步。
- 在存储时,通过散列函数计算记录的散列地址,并按此散列地址存储该记录。
- 当查找记录时,咱们通过同样的散列函数计算记录的散列地址,按此散列地址拜访该记录。
实现HashTable类
class HashTable{
table=new Array(137)
constructor(){
}
}
hash()散列函数应用霍纳算法计算键值
hash(string){
const H = 37;
var total = 0;
for (var i = 0; i < string.length; ++i) {
total += H * total + string.charCodeAt(i);
}
total = total % this.table.length;
if (total < 0) {
total += this.table.length-1;
}
return parseInt(total);
}
put()用来将数据存入散列表
put(key,data){
let pos = this.hash(key)
this.table[pos]=data
}
showDistro()示散列表中的数据
showDistro(){
for(let index=0,length=this.table.length;index<length;index++){
if(this.table[index]){
console.log(`index:${this.table[index]}`)
}
}
}
get()获取对应的键值
get(key) {
return this.table[hash(key)]
}
残缺代码
class HashTable {
table = new Array(137)
constructor() {
}
hash(string) {
const H = 37;
var total = 0;
for (var i = 0; i < string.length; ++i) {
total += H * total + string.charCodeAt(i);
}
total = total % this.table.length;
if (total < 0) {
total += this.table.length - 1;
}
return parseInt(total);
}
showDistro() {
for (let index = 0, length = this.table.length; index < length; index++) {
if (this.table[index]) {
console.log(`index:${this.table[index]}`)
}
}
}
put(key, data) {
let pos = this.hash(key)
this.table[pos] = data
}
get(key) {
return this.table[hash(key)]
}
}
碰撞解决
当散列函数对于多个输出产生同样的输入时,就产生了碰撞。解决两碰撞解决办法次要有两种:链地址法和凋谢定址法。
1.链地址法
链地址法是指实现散列表的底层数组中,每个数组元素又是一个新的数据结构,比方另一个数组,这样就能存储多个键了。应用这种技术,即便两个键散列后的值雷同,仍然被保留在同样的地位,只不过它们在第二个数组中的地位不一样罢了
结构散列表
class HashTableChains{
table=new Array(137).fill([])
constructor(){
}
}
要从新定义put()和get()办法。put()办法将键值散列,散列后的值对应数组中的一个地位,先尝试将数据放到该地位上的数组中的第一个单元格,如果该单元格里曾经有数据了,put()办法会搜寻下一个地位,直到找到能搁置数据的单元格,并把数据存储进去
put(key,data){
let pos = this.hash(key)
let index=0
if(this.table[pos][index]==undefined){
this.table[pos][index]=data
}else{
while(this.table[pos][index]!=undefined){
index++
}
this.table[pos][index]=key
this.table[pos][index+1]=data
}
}
get(key){
let hash = this.hash(key)
let index=0
if(this.table[hash][index]==key){
return this.table[hash][index+1]
}else{
while(this.table[hash][index]!=key&&this.table[hash][index]!=undefined){
index+=2
}
if(this.table[hash][index]!=undefined){
return this.table[hash][index+1]
}
}
return undefined
}
残缺代码
class HashTableChains{
table=new Array(137).fill([])
constructor(){
}
hash(string){
const H = 37;
var total = 0;
for (var i = 0; i < string.length; ++i) {
total += H * total + string.charCodeAt(i);
}
total = total % this.table.length;
if (total < 0) {
total += this.table.length-1;
}
return parseInt(total);
}
showDistro(){
for(let index=0,length=this.table.length;index<length;index++){
if(this.table[index][0] != undefined){
console.log(`index:${this.table[index]}`)
}
}
}
put(key,data){
let pos = this.hash(key)
let index=0
if(this.table[pos][index]==undefined){
this.table[pos][index]=data
}else{
while(this.table[pos][index]!=undefined){
index++
}
this.table[pos][index]=key
this.table[pos][index+1]=data
}
}
get(key){
let hash = this.hash(key)
let index=0
if(this.table[hash][index]==key){
return this.table[hash][index+1]
}else{
while(this.table[hash][index]!=key&&this.table[hash][index]!=undefined){
index+=2
}
if(this.table[hash][index]!=undefined){
return this.table[hash][index+1]
}
}
return undefined
}
}
2. 凋谢定址法
凋谢定址法隶属于一种更一般化的散列技术:凋谢寻址散列。当产生碰撞时,凋谢定址法查散列表中的下一个地位是否为空。如果为空,就将数据存入该地位;如果不为空,则持续查看下一个地位,直到找到一个空的地位为止。
线性探测法工作,须要重写put()和get()办法。
结构散列表
新增加一个属性values用来存散列表每个键对应的值
class HashTableLinear{
table=new Array(137)
values=new Array(137)
constructor(){
}
}
重写put()和get()办法
put(key,data){
let pos = this.hash(key)
if(this.table[pos]==undefined){
this.table[pos]=key
this.values[pos]=data
}else{
while(this.table[pos]!=undefined){
pos++
}
this.table[pos]=key
this.values[pos]=data
}
}
get(key){
let pos = this.hash(key)
if(this.table[pos]==key){
return this.values[pos]=data
}else{
while(this.table[pos]!=key&&this.table[pos]!=undefined){
pos++
}
if(this.table[pos]!=undefined){
return this.values[pos]=data
}
}
return undefined
}
残缺代码
class HashTableLinear{
table=new Array(137)
values=new Array(137)
constructor(){
}
hash(string){
const H = 37;
var total = 0;
for (var i = 0; i < string.length; ++i) {
total += H * total + string.charCodeAt(i);
}
total = total % this.table.length;
if (total < 0) {
total += this.table.length-1;
}
return parseInt(total);
}
showDistro(){
for(let index=0,length=this.table.length;index<length;index++){
if(this.table[index]){
console.log(`index:${this.table[index]}=>${this.values[index]}`)
}
}
}
put(key,data){
let pos = this.hash(key)
if(this.table[pos]==undefined){
this.table[pos]=key
this.values[pos]=data
}else{
while(this.table[pos]!=undefined){
pos++
}
this.table[pos]=key
this.values[pos]=data
}
}
get(key){
let pos = this.hash(key)
if(this.table[pos]==key){
return this.values[pos]=data
}else{
while(this.table[pos]!=key&&this.table[pos]!=undefined){
pos++
}
if(this.table[pos]!=undefined){
return this.values[pos]=data
}
}
return undefined
}
}
汇合
汇合是一种蕴含不同元素的数据结构。汇合中的元素称为成员。汇合的两个最重要个性是:首先,汇合中的成员是无序的;其次,汇合中不容许雷同成员存在。当你想要创立一个数据结构,用来保留一些举世无双的元素时,汇合就变得十分有用。
Set类的实现
class SetList{
dataStore=[]
constructor(){
}
}
add()增加元素
add(ele) {
if (this.dataStore.indexOf(ele) == -1) {
this.dataStore.push(ele)
return true
} else {
return false
}
}
remove()移除元素
remove(ele) {
let position = this.dataStore.indexOf(ele)
if (position != -1) {
this.dataStore.splice(position, 1)
return true
} else {
return false
}
}
size()返回数据量
size() {
return this.dataStore.length
}
show() 展现数据集
show(){
return this.dataStore
}
contains(),该办法查看一个成员是否属于该汇合
contains(ele) {
return this.dataStore.indexOf(ele) != -1
}
union() 办法执行并集操作
union(set) {
let unionSet = new SetList()
this.dataStore.forEach(item => {
unionSet.add(item)
})
set.dataStore.forEach(item => {
unionSet.add(item)
})
return unionSet
}
intersect() 办法求两个汇合的交加
intersect() {
let intersectSet = new SetList()
this.dataStore.forEach(item => {
if (set.contains(item)) {
intersectSet.add(item)
}
})
return intersectSet
}
subset() 判断是否是指标汇合的子集
subset(set) {
if (set.size() < this.size()) {
return false
}
this.dataStore.forEach(item => {
if (!set.contains(item)) {
return false;
}
})
return true
}
difference(),该办法返回一个新汇合,该汇合蕴含的是那些属于第一个汇合但不属于第二个汇合的成员。
difference(set) {
let differencetSet = new SetList()
this.dataStore.forEach(item => {
if (!set.contains(item)) {
differencetSet.add(item)
}
})
return differencetSet
}
实现代码
class SetList {
dataStore = []
constructor() {
}
add(ele) {
if (this.dataStore.indexOf(ele) == -1) {
this.dataStore.push(ele)
return true
} else {
return false
}
}
remove(ele) {
let position = this.dataStore.indexOf(ele)
if (position != -1) {
this.dataStore.splice(position, 1)
return true
} else {
return false
}
}
size() {
return this.dataStore.length
}
contains(ele) {
return this.dataStore.indexOf(ele) != -1
}
union(set) {
let unionSet = new SetList()
this.dataStore.forEach(item => {
unionSet.add(item)
})
set.dataStore.forEach(item => {
unionSet.add(item)
})
return unionSet
}
intersect() {
let intersectSet = new SetList()
this.dataStore.forEach(item => {
if (set.contains(item)) {
intersectSet.add(item)
}
})
return intersectSet
}
subset(set) {
if (set.size() < this.size()) {
return false
}
this.dataStore.forEach(item => {
if (!set.contains(item)) {
return false;
}
})
return true
}
difference(set) {
let differencetSet = new SetList()
this.dataStore.forEach(item => {
if (!set.contains(item)) {
differencetSet.add(item)
}
})
return differencetSet
}
show() {
return this.dataStore
}
}
发表回复