• 从deque到std::stack,std::queue,再到iOS 中NSArray(CFArray)


    从deque到std::stack,std::queue,再到iOS 中NSArray(CFArray)

    deque

    deque双端队列,分段连续空间数据结构,由中控的map(与其说map,不如说是数组)控制,map中每个槽指向一个固定大小的缓冲(连续的线性空间)。 
    deque的迭代器,关键的四个指针:

    cur     //所指缓冲区中的现元素
    first   //所指缓冲区中的头
    last    //所指缓冲区中的尾
    node    //指向中控的槽

    start指向中控第一个槽位的buffer中的第一个元素,finish指向中控最后一个槽位指向的buffer中的最后一个元素。 
    每次新建deque时,创建中控map和nodes,根据初始的元素个数计算开始槽位nstart和nfinish。

    map_pointer nstart = map + (map_size - num_nodes) / 2;
    map_pointer nfinish = nstart + num_nodes - 1;

    这样做的原因是双端push或pop时的平均性能最佳。

    如图,如果需要push_back,刚好finish指向的buffer将满,会向map中finish后一个槽位新建一个buffer node;对应的push_front会向map中start前一个槽位新建一个buffer node;如果map不够空间,也还是要reallocate_map,重新分配map空间迁移已有数据,释放老数据。

    std::stack,std::queue

    • stack是FILO的数据结构,只有一个出口,若以上述的deque实现,封住deque的头端开口,轻易就能实现stack,stack往往不被归为container,而被归为container adapter,源码十分简短,底层容器就是deque(当然也可以使用list:如stack<int, list >)
    class Sequence = deque<T>
    • queue是FIFO的数据结构,封住back的出口和front的入口即可轻易实现,代码同stack,也被认为是container adapter。

    NSArray(CF-1151.16源码中的CFArray)

    iOS中为什么没有实现stack,queue这样的适配器?应该是CFArray底层也是类似双端队列这样的数据结构,可以轻易实现FILO或FIFO功能,就没必要再多此一举了。 
    刚好在 CFArray.c 源码中定义了__CFArrayDeque,和各种deque相关操作的方法。

    struct __CFArrayDeque {
        uintptr_t _leftIdx;
        uintptr_t _capacity;
        /* struct __CFArrayBucket buckets follow here */
    };

    但是苹果的NSArray真实实现谁也不知道,也可能是 环形队列,这样貌似性能更高,请看这篇文章; 
    其他容器的实现。

    小结

    关于iOS为什么不实现std::stack和std::queue,可能苹果觉得NSMutableArray完全可以通过deque的性质轻易的实现FILO或FIFO特性,再实现就是多此一举了吧。 
    ps:CF源码我还没看完,继续啃吧。

  • 相关阅读:
    SpringBoot04-web
    springboot03-日志功能
    SpringBoot02-自动配置原理
    SpringBoot02
    SpringBoot01
    八大排序算法
    SpringSecurity04
    SpringSecurity03
    SpringSecurity02
    SpringSecurity01
  • 原文地址:https://www.cnblogs.com/edisongz/p/7011674.html
Copyright © 2020-2023  润新知