棧是這樣一種數據結構,越先存入棧中的數據,越後從棧中移除。後進者先出,先進者後出,這就是典型的棧結構。

當某個數據集合只涉及在一段插入和刪除數據,且滿足後進先出、先進後出的特性,應該首選棧這種數據結構。

棧的實現

棧可以用鏈表和數組實現,用數組實現的叫做順序棧,用鏈表實現的叫做鏈式棧。下面是我用數組實現的可以動態擴容的順序棧

/*
 * 支持動態擴容的棧
 */
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Stack : NSObject

- (void)push:(NSString *)value;
- (NSString *)pop;

@end

NS_ASSUME_NONNULL_END


#import "Stack.h"

@interface Stack ()
{
    NSMutableArray *_stackArray;
    NSInteger _capacity;
}

@end

@implementation Stack

- (instancetype)init {
    if (self = [super init]) {
        _capacity = 8;
        _stackArray = [NSMutableArray arrayWithCapacity:_capacity];
    }
    return self;
}

- (void)push:(NSString *)value{
    if (_stackArray.count >= _capacity) {
        _capacity = 2*_capacity;
        NSMutableArray *expandArray = [NSMutableArray arrayWithCapacity:_capacity];
        [expandArray addObjectsFromArray:_stackArray];
        _stackArray = expandArray.mutableCopy;
        NSLog(@"expand stack");
    }
    [_stackArray addObject:value];
}

- (NSString *)pop {
    if (_stackArray.count == 0) {
        return nil;
    }else{
        NSString *popStr = _stackArray.lastObject;
        [_stackArray removeLastObject];
        return popStr;
    }
}
@end
棧的應用

棧作爲一個基礎數據結構應用場景很多

  • 函數調用棧
    操作系統給每個線程分配一塊獨立的內存空間,這塊內存被組織成棧這種結構,用來存儲函數調用的臨時變量。每進入一個函數,就會將臨時變量作爲一個棧幀入棧,函數執行完畢將函數對應的棧幀出棧。


  • 棧在表達式求值中的應用
    通過兩個棧實現表達式求值,一個保存操作數的棧,另一個保存運算符的棧。從左向右遍歷表達式,數字壓入操作數棧,遇到運算符,與運算符棧的棧頂元素比較優先級,如果比棧頂元素優先級高,就將當前運算符壓入棧。如果比棧頂元素優先級低或相等,從運算符棧取棧頂運算符,從操作數棧棧頂去連個操作數進行計算,再把計算完的結果壓入棧,繼續比較。如下圖

  • 瀏覽器前進後退功能
    使用兩個棧X和Y,將首次瀏覽的頁面依次壓入棧X,點擊後退按鈕時,依次從棧X中出棧並將出棧數據依次壓入棧Y。點擊前進按鈕時,依次從棧Y中取出數據壓入棧X中。當棧X沒有數據時,說明頁面可以後退瀏覽了。當棧Y沒有數據,說明沒有頁面可以前進瀏覽了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章