棧結構-物件形式

致于数据科学家的小陈發表於2024-03-28

之前實現棧是透過 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

棧還是相對好理解的, 接下來整兩個關於用棧解決問題的經典案例.

相關文章