算法與數據結構——棧

棧是一種高效的數據結構,因爲數據只能在棧頂添加或刪除,所以這樣的操作很快,而且容易實現。

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; 
	} 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章