从链表出发封装一个自己的工具

这个是第一篇, 说一下前提; 

前些时候用到cache的时候用到了YYCache来做缓存, 然后里面提到了一个缓存算法LRU, 然后缓存算法常见的有LFU、LRU、ARC、FIFO、MRU(百度百科); 其中LRU称为 "最近最少使用算法",这里的增删主要使用链表来实现, 因为链表的增删都是O(1),(写到这里很慌, 希望没有说错, 不要被打脸)

这里有点模糊, 所以来重新复习一下数据结构以及算法, 都是实用的, 首先我找的资料呢是<<算法第四版>>, 这个是java实现的 然后参考了一下其他资料. 好的作为一个iOS开发人员, 我们首先来看一下链表的swift怎么实现

第一我们来实现一下链表

链表的swift实现

好了, 这里说几点, 第一这里的链表是使用类来实现的, 并不是用结构体,里面不能用存储属性, 而每一个节点我们都是这种存储属性, 这个用引用类型实现会比较好. 所以这里选择的是类, 而不是结构体.

第二步 我们用这个链表来实现一些基础的数据结构栈和队列和背包

栈的链表实现

队列的链表实现

背包的链表实现

大家注意到, 用链表可以很方便的实现栈和队列, 这里用数组也可以实现同样的功能,具体的区别在于对应的操作的效率,大家可以自己对比一下, 我还是比较推荐用链表实现, 因为主要是增删的操作对于链表是O(1), 对于数组是O(n)

在构建这几个基本的数据结构的时候呢, 用到了swift中关于迭代器和对列的相关协议.让链表可以像数组一样用forin循环进行操作, 并且提供了快捷的构建方法, 通过数组和字面量的两种形式

LRU算法: Least recently used,最近最少使用. 这个淘汰算法是指将最近访问过的数据插到最前面, 当超过限制之后从最后面删除数据.好吧, 现在我们来用链表来实现这个算法, 并且做一个能使在实际项目使用到的工具.

RLU算法的链表实现

这里的算法实现也是通过包装链表的一些列方法来实现的, 这里需要讨论的问题是, 那么为什么不直接用链表来实现这些功能而是用一个协议来实现, 这就是为了更好封装性和安全性, 确保在这个算法里面没有冗余的方法和不可预测错误使用方式, 所以基于链表的这一系列的实现(包括上面的栈, 队列, 以及背包和RLU算法)都是通过包装链表已有的方法进行的实现, 同时这个协议的实现也提供了一种可能性, 就是如果有不同的想法, 比如我想用一个数组来实现一个栈, 也可以通过这个协议指定的规范来统一实现相应的方法就行了. 同时需要说明的是,协议不代表你实现了这个协议就一定是实现了这样的功能, 因为你可能实现了相同的方法但是逻辑并不是这么回事, 所以协议仅仅只是一个规范, 遵守规范还是需要人为把控.

这里要提一下就是要实现线程安全或者说是原子操作, 目前在iOS里面有来之pthread的锁(自旋锁, 互斥锁),以及GCD的信号量, barrier,以及iOS10提出的unfair_lock等, 上面提到的都是比较典型的. 然后这里要提醒一下的是自旋锁和信号量在iOS平台都是不安全的方式.具体的大家可以搜索一下很容易就能明白(不愿意搜索的我简单提一下, 是由于优先级的问题造成了无法unlock). 综合很多资料比较性能之后选用的是互斥锁, 并且选用了一个比较优的封装方案(避免了闭包捕获带来的额外开销, 以及swift对于inline的优化)

互斥锁以及unfair_lock的封装

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 7,137评论 4 39
  • 这次来澳洲,被分配到了著名的大Doncaster,有着号称澳洲第二大的shopping center--Donca...
    Mr_Hap阅读 781评论 0 49
  • 大早上第一节英语课,我大概是疯了,下着雨,打着伞,提着包,踩着高跟鞋,走了40分钟找到教室,毫无疑问,迟到了。我算...
    不一样的烟火sss阅读 79评论 0 0
  • 1,用心去感知世界,感受世界的跳动,去与它们产生联系,产生共鸣,向万物学习! 2,科技再进步,也取代不了人与人的亲...
    橘子侠阅读 70评论 0 0
  • 我们现在几乎24小时都在接收各种商家的文案信息,知识博主们也在向你灌输不会写互联网文案的你正在失去职场竞争力。我们...
    清淡叽阅读 3,195评论 0 2