swift 队列和栈

本文主要是如何使用swift数组来实现队列和栈:

栈:

  • 数据先进后出,最后推进的元素是即将被推出的第一个元素;
  • 一般一个栈主要实现一下三个方法:
    • push 将对象推入栈;
    • pop 将对象弹出栈;
    • peek 只查看栈的顶层元素;
      如下所示:
//栈:数据先进后出,犹如弹夹
class FMStack<T> {
    
    var dataArray:[T] = [T]()
    //Push  将对象推入堆栈相对比较简单。 在Stack中添加以下方法:
    func push(para:T) {
        dataArray.append(para)
    }
    //Peek 查看堆栈只能查看堆栈的顶层元素。 Swift数组有一个最后一个属性。
    func peek() ->T?{
        return dataArray.last
    }
    //弹出堆栈也很简单。 只需在push方法下,在Stack中添加以下方法:
    func pop() -> T?{
        return dataArray.popLast()
        
    }
    public var isEmpty:Bool {
        return dataArray.count == 0
    }
}

队列:

  • 队列提供先进先出或先入先出的顺序。 首先插入的元素也是第一个出来的元素
  • 同样一个栈也要实现三个基本的操作:
    • push 入队方法;
    • pop 出队方法;
    • peek 查看下一个出队对象,而不删除它;
      如下所示:
//队列:先进先出,好似排队
class FMQueue<T> {
    var dataArray:[T] = [T]()
    
    public var isEmpty:Bool {
        return dataArray.count == 0
    }
    public var size:NSInteger {
        return dataArray.count
    }
    func push(para:T) {
        self.dataArray.append(para)
    }
    func peek() -> T? {
        return dataArray.first
    }
    func pop() -> T? {
        if dataArray.count > 0 {
            let first = dataArray.first
            dataArray.remove(at: (0))
            return first
        }
        return nil
    }
}

注意:swift的数组中提供了方便获取第一个元素first、最后一个元素last、获取并删除popLast最后一个元素等方法,可以合理利用.
popLastremoveLast还是有区别的,popLast当数组为空使返回nil,而removeLast则要求数组必须不为空

    /// Removes and returns the last element of the collection.
    ///
    /// Calling this method may invalidate all saved indices of this
    /// collection. Do not rely on a previously stored index value after
    /// altering a collection with any operation that can change its length.
    ///
    /// - Returns: The last element of the collection if the collection is not
    /// empty; otherwise, `nil`.
    ///
    /// - Complexity: O(1)
    @inlinable public mutating func popLast() -> Element?

    /// Removes and returns the last element of the collection.
    ///
    /// The collection must not be empty.
    ///
    /// Calling this method may invalidate all saved indices of this
    /// collection. Do not rely on a previously stored index value after
    /// altering a collection with any operation that can change its length.
    ///
    /// - Returns: The last element of the collection.
    ///
    /// - Complexity: O(1)
    @inlinable public mutating func removeLast() -> Element

如何设计一个栈,要求在基本功能的基础上,再实现返回栈中最小元素的功能,要求push、pop、getMin的操作时间复杂度都是O(1)

思路:

  • 在原有栈的基础上,再加一个栈,同步存储当前状态下数据的最小值;


    image.png

    代码如下:

class FMMinStack: NSObject {
    var data:FMStack = FMStack<Int>()
    var minData:FMStack = FMStack<Int>()
    func push(para: Int) {
        if minData.isEmpty {
            minData.push(para: para)
        }else{
            minData.push(para: getMin(para, minData.peek()!))
        }
        data.push(para: para)
    }
    func pop() -> Int? {
        _ = minData.pop()
        return data.pop()
    }
    func getMin() -> Int?{
        return minData.peek()
    }
    func peek() ->Int?{
        return data.peek()
    }
    private func getMin<T: Comparable>(_ a: T, _ b: T) -> T {
        return a < b ? a : b
    }
}

如何用栈结构实现队列结构

思路:

  • 准备一个周转栈;
  • 取:每次取的时候都从周转栈中取,每次取之前都要判断周转栈中是否有值,无值则从data原栈中导数据到周转栈中。
  • 存:存数据则是存到data原栈;
  • 看:每次看的时候也是都从周转栈中peek,单在没数据的时候优先从data原栈中导数据过来。
class FMStackToQueue: NSObject {
    var data:FMStack = FMStack<Int>()
    var zhouzhuanData:FMStack = FMStack<Int>()
    func push(para:Int){
        self.turnOverData()
        data.push(para: para)
    }
    func pop() -> Int? {
        self.turnOverData()
        return zhouzhuanData.pop()
    }
    func peek() -> Int? {
        self.turnOverData()
        return zhouzhuanData.peek()
    }
    var isEmpty:Bool {
        return zhouzhuanData.isEmpty && data.isEmpty
    }
    func turnOverData(){
        if zhouzhuanData.isEmpty {
            while data.peek() != nil {
                zhouzhuanData.push(para: data.pop()!)
            }
        }
    }
}

如何用队列结构实现栈结构

思路:

  • 准备一个周转队列;
  • 取:由于队列是先进先出,所以每次取的时候都把数据从原始data队列导入到周转队列中,但是要注意保留最后一个元素;并且将最后一个元素返回,为使存取方便,元素返回前,将原始data队列与周转队列交换(此时周转队列中存放的是原始数据,原始data队列此时无数据);
  • 存:存数据则是存到data原队列中;
  • 看:由于队列是先进先出,所以每次peek的时候也是都把数据从原始data队列导入到周转队列中,也是要注意保留最后一个元素;并且将最后一个元素返回,但是此处又要注意由于是查看,所以查看完后要把该元素在push回周转队列,然后再做交换。

代码如下:

//[1,2,3,4,5,6,7,8,9]  ->
class FMQueueToStack:NSObject{
    var data:FMQueue = FMQueue<Int>()
    var zhouzhuanData:FMQueue = FMQueue<Int>()
    
    func push(para:Int){
        data.push(para: para)
    }
    func pop() -> Int? {
        while data.size > 1 {
            zhouzhuanData.push(para: data.pop()!)
        }
        let val = data.pop()
        let middleData = data
        data = zhouzhuanData
        zhouzhuanData = middleData
        return val
    }
    func peek() -> Int? {
        while data.size > 1 {
            zhouzhuanData.push(para: data.pop()!)
        }
        let val = data.pop()
        if val != nil {
            zhouzhuanData.push(para: val!)
        }
        let middleData = data
        data = zhouzhuanData
        zhouzhuanData = middleData
        return val
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容