100天iOS数据结构与算法实战 Day02 – 栈的实现Demo

栈的特性

栈 的特性是先进后出。

动画描述

栈最常见的场景

  • 栈在iOS开发中常见的是导航栈,push pop 操作就是这种进栈出栈的操作。

  • 你调用函数的时候,这个返回地址被放到栈中,当函数结束时,使用该返回地址跳回调用者,这是记录函数调用过程的完美体现。

和栈有关的算法题目

  • Valid Parentheses

  • Basic Calculator

  • Evaluate Reverse Polish Notation

  • Implement Queue using Stacks

  • Implement Stack using Queues

  • Simplify Path

实现方式

主要有两种方法来实现栈:使用数组,使用链表。我们代码是用数组来实现的。

栈的基本操作方式

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

主要代码

 
  1. - (instancetype)initWithSize?NSUInteger)size

  2. {

  3.    self = [super init];

  4.  

  5.    if (self) {

  6.        if (size > 0) {

  7.            _stackArray = [[NSMutableArray alloc] initWithCapacity:size];

  8.            _maxStackSize = size;

  9.        }

  10.        else {

  11.            NSAssert(size != 0, @"Stack size must be > 0");

  12.        }

  13.    }

  14.    return self;

  15. }

初始化给定大小,这样是有好处的。因为如果数组容量满的时候为了增加容量,频繁的动态创建数组 copy数组会消耗一定的内存

 
  1. - (void)push?id)object

  2. {

  3.    if ([self isFull] && self.maxStackSize) {

  4.  

  5.        NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:_maxStackSize*2];

  6.        self.stackArray = [newArray mutableCopy];

  7.        _maxStackSize = _maxStackSize*2;

  8.  

  9.    }

  10.    if (object != nil) {

  11.        [self.stackArray addObject:object];

  12.  

  13.    }

  14.    else {

  15.        NSAssert(object != nil, @"You can't push nil object to stack");

  16.    }

  17. }

如果当前数组填充满了 则创建一个两倍容量的数组copy一份给原来的数组

 
  1. - (id)popLastObject

  2.  

  3. {

  4.  

  5.     id object = [self peek];

  6.  

  7.     [self.stackArray removeLastObject];

  8.  

  9.     return object;

  10.  

  11. }

如果当前数组不为空,存在数组最后一个对象则直接返回 并移除掉。

优化:

提供了一个初始化传入size的值是为了预估空间比较合理。如果没有预估好,频繁扩容会造成不断申请内存然后copy。举个例子提前初始化容量和不指定容量的对比效果图看下图:

QQ截图20190327104731.png

为了避免这个问题提供一个压缩空间的方法

 
  1. - (void)compressedStack

  2. {

  3.    int capacitySize = (int)(_maxStackSize * 0.9);

  4.    int stackSize = (int)(self.stackArray.count);

  5.    if( stackSize < capacitySize ) {

  6.        NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:stackSize];

  7.        self.stackArray = [newArray mutableCopy];

  8.        _maxStackSize = stackSize;

  9.  

  10.    }

  11. }

如果当前栈内元素个数小于容量的90% ,那么压缩栈把容量设置为当前栈的实际元素个数。

栈操作复杂度

压栈操作是将新元素压入数组的尾部,而不是头部。在数组的头部插入元素是一个很耗时的操作,它的时间复杂度为 O(n),因为需要将现有元素往后移位为新元素腾出空间。而在尾部插入元素的时间复杂度为 O(1);无论数组有多少元素,这个操作所消耗的时间都是一个常量。

栈的实现Demo

群昵称:ios-Swift/Object C开发上架
群号: 869685378   找ios马甲包开发者合作,有兴趣请添加Q 51259559

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值