棧和佇列的基本應用
阿新 • • 發佈:2018-12-26
棧的使用
給定一個字串,只包含{,[, (,),],},判斷字串的括號匹配是否合法。如(),()[]{}是合法的,而(]是不合法的
假設一個字串’{[()]}’,當我們遍歷時遇到左操作符的時候,就將它壓入棧中,當遇到右操作符的時候,就與棧頂的元素匹配,如果match就將棧頂的左操作符彈出,繼續遍歷。如果沒有match的話就返回false。如果遍歷結束的時候棧也為空,這個字元就是合法的。
function isValid(str){
for(var i = 0, len = str.length; i < len; i++){
if(str[i] == '(' || str[i] == '{' str[i] == '[' ){
stack.push(str[i])
} else {
if(stack.size == 0) return false;
var c = stack.pop();
//省略match定義
if(!str[i].match(c)){
return false;
}
}
}
if(stack.size == 0 ) {
return true;
} else {
return false;
}
}
棧頂元素反映了在巢狀的層次關係中,最近的需要匹配的元素
棧和遞迴的緊密關係
我們先看一下二叉樹的先序遍歷
function preorder(node){
if(node){
console.log(node.value);
preorder(node.left);
preorder(node.right);
}
}
我們來看一下具體的遍歷,假設我們只有三個節點,父節點是1,左節點是2,右節點是3。我們首先使用根節點呼叫函式preorder,然後使用節點2呼叫了函式preorder,再使用節點3呼叫了函式preorder。這三次preorder的傳入引數是不同的,那麼這三個函式的呼叫順序是怎麼樣的?我們可以抽象為根節點呼叫時,執行到節點2呼叫的時候停住了,接著執行一個子函式也就是節點2的呼叫,直到節點2呼叫結束之後,再進行節點3子函式的呼叫。那麼作業系統就是通過棧來實現這樣一個操作。根節點呼叫的函式先被壓入棧中開始執行,這時遇到了函式棧節點2。在節點2的函式被壓入棧之後立即執行,等到執行完之後返回值(或不返回),然後節點2的函式被彈出。節點2的函式被彈出之後,節點1的函式繼續執行,節點3的函式被壓入並立即執行。
佇列的基本應用
佇列比較常用的是廣度優先遍歷,在樹中是層序遍歷,在圖中是無權圖的最短路徑
我們來看一下二叉樹的層序遍歷
var node;
levelOrder(root){
var result = [];
if(root == null) return result;
queue.push(root);
while(!queue.empty()){
var node = queue.front();
if(node.left) queue.push(node.left);
if(node.right) queue.push(node.right);
result.push(node.value);
}
}