除了学习在C ++中实现我自己的双向链表的学术方面之外,当已经有std :: list时,实现我自己的双向链表是否有任何实际的现实优势?我能否为自己的某项任务提高效率,或者多年来std :: list已被提炼得如此之多以至于在大多数情况下它是双向链表的最佳实现?
答案 0 :(得分:7)
当已经有std :: list时,实现我自己的双向链表有什么实际的现实优势吗?
可能不是。
我能否为自己的某项任务提高效率,
也许 - 取决于任务。例如,您可能只需要一个单链表,最终可能会更快。
或者std :: list多年来经过多次改进,在大多数情况下它是双向链表的最佳实现?
可能。
所有这些东西的最佳答案可能是“使用标准实现,直到它不起作用,然后弄清楚你将要做些什么。”
答案 1 :(得分:2)
“为什么我要在C ++中实现双向链表?”
你不会。即使你需要一个双向链表,你也可以避免重新发明轮子并使用现有的实现。
答案 2 :(得分:2)
如果您不得不提出这个问题,答案是否。
答案 3 :(得分:1)
您几乎不会想要或不需要实现自己的list
。就此而言,如果标准库涵盖了您的任何,您几乎不会想要或需要重新实现它们。
有例外。那些例外是......非常......出于性能原因,例外情况通常是在性能要求极端时。但是,只有当您已经证明标准库提供的功能对于您的特定用途而言是一个可衡量的问题时,才能负责任地做出这些例外。
答案 4 :(得分:0)
是的,对于某项任务,双向链表可能比std::list
更有效。 std::list
中存在算法复杂性权衡,您的任务可能会受益于相反的决策。
具体来说,C ++ 11中需要std::list
,并且在C ++ 03中推荐使用size()
来获得常量splice()
。也就是说,元素的数量必须存储在对象中。
这意味着splice()
的4参数版本必然具有线性复杂性,因为它需要计算从一个列表移动到另一个列表的元素数量,以便更新两个大小(在某些特殊情况下,例如,在拼接后源列表为空,或者两个列表是同一个对象)。
但是,如果您正在进行大量拼接,那么您可能更愿意使用相反的方法 - 常量时间size()
和std::list
函数,它是线性时间的最坏的情况(当列表上的拼接比上次更新大小时更近)。
实际上,GNU的{{1}}实现做出了这个选择,并且必须改变C ++ 11的一致性。所以即使这是你想要的,你也不一定要自己完全实现它。只需清除旧的GNU代码并更改名称,使其成为有效的用户代码。