繁体   English   中英

从 C++ 中的 std::vector 的开头删除

[英]Removing from the beginning of an std::vector in C++

我可能在这里遗漏了一些非常基本的东西,但这是我想知道的 -

我们知道从 C++ 中的 std::vector ( vector[0] ) 开头删除一个元素是一个 O(n) 操作,因为所有其他元素都必须向后移动一个位置。

但是为什么它没有实现,使得指向第一个元素的指针向前移动一个 position 以便现在向量从第二个元素开始,本质上,第一个元素被删除? 这将是一个 O(1) 操作。

std::array 和 C 风格的 arrays 是固定长度的,你根本不能改变它们的长度,所以我认为你有一个错字,而是指std::vector

“为什么会这样?” 有点历史问题。 从角度来看,如果您的系统库允许将未使用的 memory 返还给操作系统,那么您的“向后移动”技巧将不允许以后重用前第一个元素的 memory。

此外,std::vector 来自带有freemalloc类的调用的系统(就像它们基本上仍然在每个操作系统中使用一样),您需要在其中保留指向已分配区域开头的指针,以便能够释放它稍后的。 因此,您必须绕过 std::vector 结构中的另一个指针才能释放该向量,而这只有在有人从前面删除时才有用。 如果你从前面删除,你可能最好使用反向向量(并从最后删除),或者向量不是正确的数据结构。

像这样实现向量并非不可能(尽管它不是std::vector )。 除了指向底层数组的指针之外,您还需要保留指向第一个元素的指针(或者可以存储一些偏移量,但无论如何放置,都需要在向量中存储更多数据)。

考虑到这仅对一个非常具体的用例有用:擦除第一个元素。 好吧,一旦你知道了,当有剩余空间时,你也可以在前面插入一个元素时受益。 如果还有剩余空间,那么即使在前半部分插入也可以通过仅移动前半部分来受益。

然而,这一切都不符合容量的概念。 使用std::vector您可以准确地知道在重新分配发生之前可以添加多少元素: capcity() - size() 有了你的提议,这将不再成立。 擦除第一个元素会以一种奇怪的方式影响容量。 这将使所有用例的向量的接口和用法复杂化。

此外,在其他任何地方擦除元素仍然不是O(1) 总的来说,它会产生成本并增加向量的任何使用的复杂性,同时仅在非常狭窄的用例中带来优势。

如果您确实发现自己需要经常擦除前面的元素,那么您可以反向存储向量,并且擦除最后一个元素已经是O(1) ,或者使用不同的容器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM