Swift中队列的实现

  先占坑,有时间再详细解释

//MARK: - 队列的基本实现
public struct Queue<T> {
    
    // 泛型数组:用于存储数据元素
    fileprivate var data = [T]()
    
    
    
    /// 构造函数:创建一个空的队列
    public init() {}
    
    
    
    /// 入队列操作:将元素添加到队列的末尾
    /// -复杂度: O(1)
    /// -参数element: 一个类型为T的元素
    public mutating func enqueue(_ element: T) {
        data.append(element)
    }
    
    
    
    /// 出队列操作:删除并返回队列中的第一个元素
    /// -returns:
    /// -如果队列不为空,则返回第一个类型为T的元素
    /// -如果队列为空,则返回nil
    public mutating func dequeue() -> T? {
        return data.removeFirst()
    }

    
    
    /// 返回队列中的第一个元素(不删除)
    /// -returns:
    /// -如果队列不为空,则返回第一个类型为T的元素
    /// -如果队列为空,则返回nil
    public func peek() -> T? {
        return data.first
    }
    
    
    
    /// 将队列重置为空状态
    public mutating func clear() {
        data.removeAll()
    }
    
    
    
    /// 返回队列中元素的个数
    public var count: Int {
        return data.count
    }
    
    
    
    /// 计算属性:返回队列的存储容量
    /// - get:获取队列的存储空间,但不会分配新的存储空间
    /// - set:分配足够的空间来存储指定数量的元素
    public var capacity: Int {
        get {
            return data.capacity
        }
        set {
            data.reserveCapacity(newValue)
        }
    }
    
    
    
    /// 检查队列是否已满
    /// -returns: 如果队列已满,则返回true,否则返回false
    public func isFull() -> Bool {
        return count == data.capacity
    }
    
    
    
    /// 检查队列是否为空
    /// - returns: 如果队列为空,则返回true,否则返回false
    public func isEmpty() -> Bool {
        return data.isEmpty
    }
    
    
    
    /// 检查队列中的索引是否合法
    fileprivate func checkIndex(_ index: Int) {
        if index < 0 || index > count {
            fatalError("Index out of range")
        }
    }
}



// MARK: - 打印队列及其类型时,输出简洁漂亮的格式
extension Queue: CustomStringConvertible, CustomDebugStringConvertible {
    
    /// 在打印队列及其元素时,输出简洁漂亮的格式
    /// 如果不实现这些代码,打印队列的结果为:Queue<Int>(data: [125, 130])
    /// 实现下面这些代码之后,打印队列的结果为:[125, 130]
    /// - returns: 返回队列及其元素的文本表示
    public var description: String {
        return data.description
    }
    
    
    /// 打印时输出简洁漂亮的格式,主要用于调试
    /// - returns: 返回队列及其元素的文本表示,适用于调试
    public var debugDescription: String {
        return data.debugDescription
    }
}



// MARK: - 以现有队列实例为基础,创建新的队列实例
extension Queue {
    
    /// 构造函数:用于从序列中创建队列(可参见Stack中的相关注释)
    /// 实现这个方法可以让你通过现有的队列实例来创建一个新的队列实例:
    ///     // var queue: Queue = [1, 2, 3]
    ///     // var myQueue = Queue(queue)  // 使用现有的队列实例queue来创建新的队列实例
    ///
    /// - 参数elements:其类型为S,并且限定遵守Sequence协议,where关键字限制了这个构造函数只
    ///                对元素类型是T类型的序列有效;
    public init<S: Sequence>(_ elements: S) where S.Iterator.Element == T {
        
        // 将一个elements序列添加到数组data末尾
        data.append(contentsOf: elements)
    }
}



// MARK: - 使用字面量语法来创建队列实例
extension Queue: ExpressibleByArrayLiteral {
    
    /// 使用字面量语法来创建队列实例
    public init(arrayLiteral elements: T...) {
        self.init(elements)
    }
}



// MARK: - 根据索引返回指定的位置
/// 补充说明一点,因为MutableCollection协议是遵守Collection协议的,
/// 而Collection协议又是遵守Sequence协议的,所以从理论上讲,我们这里
/// 已经遵守了MutableCollection协议,后面就没必要再遵守Collection
/// 协议和Sequence协议了。但是,从语义和逻辑清晰的角度来讲,明确遵守某
/// 个协议有利于我们对代码的理解
extension Queue: MutableCollection {
    
    /// 队列的起始索引
    /// - returns:返回队列开始的索引
    public var startIndex: Int {
        return 0
    }
    
    
    
    /// 队列的末尾索引
    /// - returns:返回队列末尾的索引,如果队列为空,则返回0,否则返回count - 1
    public var endIndex: Int {
        return count == 0 ? 0 : count - 1
    }
    
    
    /// 返回指定位置后面的索引,并且索引i必须比endIndex小,否则越界
    /// - returns:返回指定索引后面的位置
    public func index(after i: Int) -> Int {
        
        // 检查索引值i是否合法
        checkIndex(i)
        
        // 返回i后面的索引
        return data.index(after: i)
    }
    
    
    
    /// 通过指定的下标值来获取/设置队列中的元素
    /// - get:获取队列中指定下标元素的值
    /// - set:修改队列中指定下标元素的值
    public subscript(index: Int) -> T {
        
        get {
            // 检查下标值是否合法
            checkIndex(index)
            return data[index]
        }
        
        set(newValue) {
            // 检查下标值是否合法
            checkIndex(index)
            data[index] = newValue
        }
    }
}


// MARK: - 添加for...in等循环支持
extension Queue: Sequence {
    
    /// 返回此序列的元素的迭代器
    /// - 复杂度: O(1)
    public func makeIterator() -> AnyIterator<T> {
        return AnyIterator(IndexingIterator(_elements: data.lazy))
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,884评论 25 707
  • (一)、PHP implode() 函数 把数组元素组合为字符串: <?php $arr = array('Hel...
    九点四十阅读 562评论 0 0
  • 最近直播手帐课的女孩儿叫babe,手帐写的很棒,说话有点台湾腔,听起来蛮有意思的。她说她第一次直播教手帐有点紧张。...
    橘汁儿阅读 404评论 2 3
  • 昨天将猫叔的分享又听了一遍,理解更深了一步。 目标 第一个讲到的是战略力,意思是对于未来,要有战略目标。将自己的目...
    SukiQi苏琪阅读 391评论 0 3
  • 树的非递归代码(Java实现) 建树: 树节点定义: 层次遍历、前中后遍历的代码: 测试用例:input.txt ...
    lxhao阅读 579评论 0 1