一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
前言
上期我们基于数组的创建了一个栈类,但是并不是最完美的,首先他会消耗更多的内存空间,其次在数据量过大时,消耗的时间会更久。本期我们基于对象实现一个栈类。
我们先来回顾一下,栈都拥有哪些方法:
-
push :添加一个元素到栈顶(因为存储结构的变化,目前只做添加单个元素)
-
pop :移除栈顶的元素,同时返回被移除的元素
-
top :返回栈顶的元素,不对栈进行任何处理
-
isNull :判断栈是否为空,如果为空返回true,否则返回false
-
clear :清空栈
-
size :返回栈的元素个数
编码实现
定义一个栈类
class Stack{
constructor(){
// 基于对象存储
this.items = {}
// 定义一个变量,辅助存储栈并获得栈的大小
this.nums = 0
}
}
push
push(data){
this.items[this.nums] = data
this.nums++
}
pop
pop(){
// 需要判断栈是否为空,为空返回undefined
if(this.isNull()){
return undefined
}
//因为push 方法最后会讲nums + 1,所以此处需要 -1 来保证nums的值对应栈的顶部
this.nums--
//定义一个变量保存栈顶元素
const popData = this.items[this.nums]
//删除栈顶元素
delete this.items[this.nums]
return popData
}
top
top(){
// 需要判断栈是否为空,为空返回undefined
if(this.isNull()){
return undefined
}
//因为top方法不改变栈的元素,所以此处不必改变nums的值
return this.items[this.nums - 1]
}
isNull
isNull(){
return this.nums === 0
}
clear
clear(){
this.items = {}
this.nums = 0
}
size
size(){
return this.nums
}
完整代码如下:
class Stack {
constructor(){
this.items = {}
this.nums = 0
}
push(data){
this.items[this.nums] = data
this.nums++
}
pop(){
if(this.isNull()){
return undefined
}
this.nums--
const popData = this.items[this.nums]
delete this.items[this.nums]
return popData
}
top(){
if(this.isNull()){
return undefined
}
return this.items[this.nums - 1]
}
isNull(){
return this.nums === 0
}
clear(){
this.items = {}
this.nums = 0
}
size(){
return this.nums
}
}
const stack = new Stack()
console.log(stack.isNull()); //true
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
console.log(stack.size()); //5
console.log(stack.top()); //5
console.log(stack.pop()); //5
console.log(stack.top()); //4
console.log(stack.size()); //4
console.log(stack.isNull()); //false
stack.clear()
console.log(stack.isNull()); //true
console.log(stack.size()); //0
总结
让我们对两种实现方法做个比较。
const stark1 = new StackByArrar()
const stark2 = new StackByObject()
for(let i = 0;i < 100000000;i++){
stark1.push(i)
}
for(let i = 0;i < 100000000;i++){
stark2.push(i)
}
console.time('starkByArray')
stark1.push('123')
stark1.top()
stark1.pop()
stark1.size()
stark1.isNull()
console.timeEnd('starkByArray')
console.time('starkByObject')
stark2.push('123')
stark2.top()
stark2.pop()
stark2.size()
stark2.isNull()
console.timeEnd('starkByObject')
可以看到由于采用对象存储,对于对象的读取,时间复杂度为O(1),数据量过大时消耗时间也会比数组更短。
由于对象实现比数组多一个变量,数组由于是顺序存储,又比对象更占空间,从结果看,所占空间五五开。各位看官,你认为的对象存储是否是这样呢?评论区我们可以交流讨论。