【问题标题】:Why does C++ not provide a First-In-First-Out singly-linked list?为什么 C++ 不提供先进先出单链表?
【发布时间】:2020-04-06 13:12:44
【问题描述】:

在C++标准库中,list是双向链表; forward_list 是单链表,但只支持后进先出。

但是,先进先出单链表已被广泛使用,因为它比其他类似列表的容器(forward_list 除外)具有较低的空间开销。所以我想知道:

为什么 C++ 不提供先进先出单链表?

【问题讨论】:

  • std::deque 怎么样?
  • 不是真的,你可以为队列选择容器类型,例如std::queue<T,std::list<T>>queue只是一个适配器
  • std::forward_list 怎么样?
  • 如果您担心空间开销,那么不言而喻,与双端队列相比,链表对每个元素都有不必要的开销。如果没有更复杂的分配器,每个元素都是一个单独的免费存储分配,其中包括至少与其大小有关的元数据。在列表本身中,每个元素都带有一个指针。
  • 你真的需要单链表吗?从性能角度来看,它基本上是您可以使用的最糟糕的数据结构。双端队列应该快几个数量级。

标签: c++ stl containers standards c++20


【解决方案1】:

您可以轻松地自己创建一个,方法是在forward_list 中添加一个前端迭代器来实现back()push_back()

template<class T>
struct fifo_list {
    std::forward_list<T> base;
    std::forward_list<T>::iterator before_end = base.before_begin();
    fifo_list(fifo_list const& other) { for (auto t : other.base) push_back(t); }
    fifo_list(fifo_list&&) = default;
    auto front() { return base.front(); }
    void pop_front() { base.pop_front(); }
    auto back() { return *before_end; }
    void push_back(T t) { before_end = base.insert_after(before_end, t); }
};

这可以与std::queue 适配器一起使用。

与维护before_end 迭代器相关的开销大概是这个设施(backpush_back)尚未包含在forward_list 中的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多