栈结构-对象形式

之前实现栈是通过 js 数组实现的, 其实也可以用对象形式来实现.

class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
}

向栈顶插入元素

即通过对象新增属性 count 和元素值 item 的形式即可.

class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
  // 入栈
  push(item) {
    this.obj[this.count] = item 
    this.count += 1
  }
}

用数字或者变量字符啥的作为对象的 key 会自动转换为字符的. 假设我们 push 两个元素 666, 888 进去.

const stack = new Stack()

stack.push(666)
stack.push(888)

则在内部 obj 的值和 count 属性显示如下:

obj = {
    0: 666,
    1: 888
}

判断栈是否为空

即通过判断 count 的值是否为 0 即可, 顺便实现栈的 size 方法, 本质是同一个东西.

class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
  // 栈是否为空
  isEmpty() {
    return this.count == 0
  }
  // 栈的大小
  size() {
    return this.count
  }
}

从栈顶移除元素

  • 当栈为空时, 返回 undefined 即可
  • 当栈有值, 因为底层对象的键是通过 count 属性从 0 开始递增的, 则长度为 count - 1
class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
  isEmpty() {
    return this.obj.count == 0
  }
  // 出栈
  pop() {
    if (this.isEmpty()) return undefined
      
    this.count= this.count - 1
    const item = this.obj[this.count]

    delete this.obj[this.count]
    return item
  }
}

这里的栈顶元素的键要根据 count -1 还是举例说明一下:

const obj = {}
let count = 0 

obj[count] = 1
count += 1

obj[count] = 2
count += 1

obj[count] = 3
count += 1

console.log(obj, count);
PS F:\algorithms> node .\stack_object
{ '0': 1, '1': 2, '2': 3 } 3

可以看到, count 是3, 但最后一个元素是 2 , 这样就很清晰了.

也顺带来简单测试一下入栈, 出栈的操作是否合适.

const stack = new Stack()
stack.push(666)

console.log(stack.pop());
console.log(stack.size());
console.log(stack.isEmpty());
PS F:\algorithms> node .\stack_object
666
0
true

查看栈顶元素

即实现 peek 方法, 返回栈顶元素但不做任何操作.

class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
  // 查看栈顶元素 
  peek() {
    if (this.isEmpty()) return undefined
    return this.obj[this.count -1]
  }
}

清空栈元素

最简单的方法是让其指向空对象, 或者通过不断地 pop.

class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
  // 清空栈
  clear() {
    this.count = 0
    this.obj = {}
  }
  // 当然也可以不断地 pop
  clear2() {
    while (! this.isEmpty()) {
      this.pop()
    }
  }
}

栈的 toString 方法

在数组版本的栈中, 可以直接调用其 toString 方法, 而当前的对象版本则可以手动实现一下.

class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
  // toString 方法
  toString() {
    if (this.isEmpty()) return ''

    let objString = `${this.obj[0]}`
    for (let i = 1; i < this.count; i++) {
      objString = `${objString}, ${this.obj[i]}`
    }
    return objString
  }
}

至此, 我们用 js 对象作为底层实现的栈也就好了. 但注意这是有缺陷的, 就是在于 countojb 这两个属性是得不到保护的. 具体咋弄就不讨论了, 主要还是以学习为主的, 自己玩.

class Stack {
  constructor() {
    // 用一个 count 属性来记录栈的大小
    this.count = 0
    this.obj = {}
  }
  // 入栈
  push(item) {
    this.obj[this.count] = item 
    this.count += 1
  }
  // 栈是否为空
  isEmpty() {
    return this.count == 0
  }
  // 栈的大小
  size() {
    return this.count
  }
  // 出栈
  pop() {
    if (this.isEmpty()) return undefined

    this.count= this.count - 1
    const item = this.obj[this.count]

    delete this.obj[this.count]
    return item
  }
  // 查看栈顶元素 
  peek() {
    if (this.isEmpty()) return undefined
    return this.obj[this.count -1]
  }
  // 清空栈
  clear() {
    this.count = 0
    this.obj = {}
  }
  // 当然也可以不断地 pop
  clear2() {
    while (! this.isEmpty()) {
      this.pop()
    }
  }
  // toString 方法
  toString() {
    if (this.isEmpty()) return ''

    let objString = `${this.obj[0]}`
    for (let i = 1; i < this.count; i++) {
      objString = `${objString}, ${this.obj[i]}`
    }
    return objString
  }
}


// test 
const stack = new Stack()
stack.push(666)

console.log(stack.pop());
console.log(stack.size());
console.log(stack.isEmpty());

stack.push(888)
stack.push(999)
stack.push(111)

console.log('栈元素是: ', stack.toString())
console.log('栈顶元素是: ', stack.peek());

PS F:\algorithms> node .\stack_object
666
0
true
栈元素是:  888, 999

栈还是相对好理解的, 接下来整两个关于用栈解决问题的经典案例.

posted @ 2024-03-28 13:32  致于数据科学家的小陈  阅读(21)  评论(0编辑  收藏  举报