棧
棧是一種高效的數據結構,因爲數據只能在棧頂添加或刪除,所以這樣的操作很快,而且容易實現。
1.對棧的操作
棧是一種特殊的列表,棧內的元素只能通過列表的一端訪問,這一端稱爲棧頂。
- 後入先出(LIFO,last-in-first-out)的數據結構。
- 對棧的兩種主要操作是將一個元素壓入棧和將一個元素彈出棧。
- 入棧使用 push() 方法。
- 出棧使用 pop() 方法。pop() 方法雖然可以訪問棧頂的元素。
- peek() 方法則只返回棧頂元素,而不刪除它。
2.棧的實現
實現一個棧,當務之急是決定存儲數據的底層數據結構。這裏採用的是數組。 我們的實現以定義 Stack 類的構造函數開始:
function Stack() {
this.dataStore = [];
this.top = 0;
this.push = push;
this.pop = pop;
this.peek = peek;
}
我們用數組 dataStore 保存棧內元素,構造函數將其初始化爲一個空數組。變量 top
記錄棧頂位置,被構造函數初始化爲0,表示棧頂對應數組的起始位置0。如果有元素被壓入棧,該變量的值將隨之變化。
2.1 push()的實現
當向棧中壓入一個新元素時,需要將其保存在數組中變量 top 所對 應的位置,然後將top
值加 1,讓其指向數組中下一個空位置。代碼如下所示:
function push(element) {
this.dataStore[this.top++] = element;
}
2.2 pop()的實現
pop()
方法恰好與 push()
方法相反——它返回棧頂元素,同時將變量 top 的值減 1:
function pop() {
return this.dataStore[--this.top];
}
2.3 peek()方法的實現
方法返回數組的第 top-1 個位置的元素,即棧頂元素:
function peek() {
return this.dataStore[this.top-1];
}
如果對一個空棧調用 peek() 方法,結果爲 undefined
。這是因爲棧是空的,棧頂沒有任何元素。
2.4 length()方法的實現
有時候需要知道棧內存儲了多少個元素。length() 方法通過返回變量 top 值的方式返回棧 內的元素個數: function length() { return this.top; } 最後,可以將變量 top 的值設爲 0,輕鬆清空一個棧: function clear() { this.top = 0; }
3.實戰
3.1迴文
迴文是指這樣一種現象:一個單詞、短語或數字,從前往後寫和從後往前寫都是一樣的。 比如,單詞“dad”、“racecar”就是迴文;如果忽略空格和標點符號,下面這個句子也是回 文,“A man, a plan, a canal: Panama”;數字 1001 也是迴文。
使用棧,可以輕鬆判斷一個字符串是否是迴文。我們將拿到的字符串的每個字符按從左至右的順序壓入棧
。當字符串中的字符都入棧後,棧內就保存了一個反轉後的字符串,最後的字符在棧頂,第一個字符在棧底,字符串完整壓入棧內後,再通過持續彈出棧中的每個字母就可以得到一個新字符串
,該字符串剛好與原來的字符串順序相反。我們只需要比較這兩個字符串
即可,如果它們相等,就是一個迴文。
function isPalindrome(word) {
var s = new Stack();
for (var i = 0; i < word.length; ++i) {
s.push(word[i]);
}
var rword = "";
while (s.length() > 0) {
rword += s.pop();
}
if (word == rword) {
return true;
}else {
return false;
}
}