資料結構第一篇 棧

weixin_34365417發表於2018-05-08

棧的特性

棧 的特性是先進後出。

棧的思考

壓棧操作是將新元素壓入陣列的尾部,而不是頭部。在陣列的頭部插入元素是一個很耗時的操作,它的時間複雜度為 O(n),因為需要將現有元素往後移位為新元素騰出空間。而在尾部插入元素的時間複雜度為 O(1);無論陣列有多少元素,這個操作所消耗的時間都是一個常量。

棧在移動端 iOS開發中最常見的場景

棧在iOS開發中常見的是導航棧,push pop 操作就是這種進棧出棧的操作。

具體自己實現棧的操作方式

DSStack *testStack = [[DSStack alloc] initWithSize:4];
    [testStack push:@"1"];
    [testStack push:@"2"];
    [testStack push:@"5"];
    [testStack popLastObject];
    NSLog(@"%@",testStack);

下面自己實現一個棧結構主要是用陣列實現。大致看幾個關鍵方法:

- (instancetype)initWithSize:(NSUInteger)size
{
    self = [super init];
    
    if (self) {
        if (size > 0) {
            _stackArray = [[NSMutableArray alloc] initWithCapacity:size];
            _maxStackSize = size;
        }
        else {
            NSAssert(size != 0, @"Stack size must be > 0");
        }
    }
    return self;
}

初始化給定大小,這樣是有好處的。因為如果陣列容量滿的時候為了增加容量,頻繁的動態建立陣列 copy陣列會消耗一定的記憶體

- (void)push:(id)object
{
    if ([self isFull] && self.maxStackSize) {
        
        NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:_maxStackSize*2];
        self.stackArray = [newArray mutableCopy];
        _maxStackSize = _maxStackSize*2;

    }
    if (object != nil) {
        [self.stackArray addObject:object];

    }
    else {
        NSAssert(object != nil, @"You can't push nil object to stack");
    }
}

如果當前陣列填充滿了 則建立一個兩倍容量的陣列copy一份給原來的陣列

- (id)popLastObject

{

    id object = [self peek];

    [self.stackArray removeLastObject];

    return object;

}

如果當前陣列不為空,存在陣列最後一個物件則直接返回 並移除掉。

提問:朋友說擴充兩倍可能浪費空間。

提供了一個初始化傳入size的值是為了預估空間比較合理。如果沒有預估好,頻繁擴容會造成不斷申請記憶體然後copy。舉個例子提前初始化容量和不指定容量的對比效果圖看下圖:


1304277-eff0708a048c4a18.jpg
對比圖

為了避免這個問題提供一個壓縮空間的方法

- (void)compressedStack
{
    int capacitySize = (int)(_maxStackSize * 0.9);
    int stackSize = (int)(self.stackArray.count);
    if( stackSize < capacitySize ) {
        NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:stackSize];
        self.stackArray = [newArray mutableCopy];
        _maxStackSize = stackSize;

    }
}

如果當前棧內元素個數小於容量的90% 那麼壓縮棧把容量設定為當前棧的實際元素個數

最後demo:https://github.com/renmoqiqi/DataStructureDemo

相關文章