資料結構學習筆記--棧

Ilion發表於2019-02-12

為什麼要學習資料結構?

相信大家都聽過一句話程式=資料結構+演算法,資料結構和演算法是脫離程式語言而存在的,不同的語言有不同的實現版本,但內在的邏輯卻不會有變化,所體現的程式設計思想不會有變化。雖然前端可能對資料結構和演算法的要求沒有那麼高,但是作為一個程式設計師資料結構是我們應該掌握的基本知識。

1、棧的定義

棧是一種特殊的線性表,我們只能夠在棧頂對其進行操作,有著先進後出的特點

資料結構學習筆記--棧

2、棧的實現

實現棧可以用陣列來儲存資料,這是最簡單的方式。

// 定義一個stack類
function Stack() {
    let items = [] // 用於儲存資料,
}

複製程式碼

2.1定義棧的一些常用的方法

  • push 新增一個元素到棧頂
  • pop 彈出棧頂元素
  • top 返回棧頂元素,注意,不是彈出
  • isEmpty 判斷棧是否為空
  • size 返回棧裡元素的個數
  • clear 清空棧

你還可以定義其他你認為你將要用到的方法,這些只是一些常用的方法

push

// 新增一個元素到棧頂
this.push = (data) => {
    items.push(data)
}
複製程式碼

pop

// 刪除棧頂元素
this.pop = () => {
    return items.pop()
}
複製程式碼

top

// 返回棧頂元素
this.top = () => {
    return items[items.length - 1]
}
複製程式碼

isEmpty

// 檢查棧是否為空
this.isEmpty = () => {
    return items.length === 0
}
複製程式碼

size

// 返回棧的大小
this.size = () => {
    return items.length
}
複製程式碼

clear

// 清空棧
this.clear = () => {
    items = []
}
複製程式碼

最終程式碼

function Stack() {
    let items = []
    this.push = (data) => {
        items.push(data)
    }
    this.pop = () => {
        return items.pop()
    }
    this.top = () => {
        return item[items.length - 1]
    }
    this.isEmpty = () => {
        return items.length === 0
    }
    this.size = () => {
        return items.length
    }
    this.clear = () => {
        items = []
    }
}

複製程式碼

3、棧的應用

3.1、檢查括號的合法性

下面的字串中包含小括號,請編寫一個函式判斷字串中的括號是否合法,所謂合法,就是括號成對出現

  • sdf(ds(ew(we)rw)rwqq)qwewe 合法
  • (sd(qwqw)sd(sd)) 合法
  • ()()sd()(sd()fw))( 不合法

思路分析

括號存在巢狀關係,也存在並列關係,如果是用陣列儲存這些括號,然後再想辦法一對一對的抵消掉,似乎是一個可行的辦法,可是如何判斷一個左括號對應的是哪個右括號呢?站在陣列的肩膀上思考這個問題,就陷入到一種無從下手的絕望之中。

現在,我們站在棧的肩膀上思考這個問題,解題的步驟就非常簡單,我們可以使用for迴圈遍歷字串的每一個字元,對每個字元做如下的操作:

  • 遇到左括號,就把左括號壓如棧中
  • 遇到右括號,判斷棧是否為空,為空說明沒有左括號與之對應,缺少左括號,字串括號不合法,如果棧不為空,則把棧頂元素移除,這對括號抵消掉了

當for迴圈結束之後,如果棧是空的,就說明所有的左右括號都抵消掉了,如果棧裡還有元素,則說明缺少右括號,字串括號不合法。

程式碼實現

function is_leagl(str) {
    let stack = new Stack()
    for(let i = 0; i < str.length; i ++) {
        let item = str[i]
        if(item === '(') { // 左括號入棧
            stack.push(item)
        } else if (item === ')') { // 右括號
            if(stack.isEmpty()) { // 檢查棧是否為空
                return false
            } else { // 不為空彈棧
                stack.pop()
            }
        }
    }
}
複製程式碼

棧還有其他很多的應用比如:1、計算代數式;2、構造表示式;3、用於函式得呼叫等等。

4、最後

在學習了棧之後瞭解到了它的方便之處,雖然是基於資料來實現的,但是在某些場景使用起來比資料更加方便快捷。後面會繼續學習佇列、連結串列、樹、圖等其他資料結構來豐富自己的知識。

相關文章