【发布时间】:2019-10-02 09:38:48
【问题描述】:
我与我的教授进行了以下交流,这不是很令人满意。我包括了我的部分交流,这应该足以让我的观点得到理解。
“对于向量,C++实现是否遍历旧的动态分配数组的每个元素并释放它? (编辑:我的意思是,在调整大小和添加元素时,通过推回或调整大小)
我特别好奇,因为这本书试图证明链表很麻烦,因为每次都必须遍历。在我看来,向量在这方面并没有很大的优势。
我可以看到向量的主要好处是方便和快速访问,但仅此而已。例如,每次您尝试执行访问以外的操作时,您都将遍历所有内容以移动和释放内存。对吗?”
在他回复后,我补充道。
“xxxx教授,
我出去测试了,事实上,如果你调整大小或 push_back,地址就会改变,所以我假设旧地址被释放是正确的。我只能假设程序必须去每个元素来释放它,如果这是正确的,那么插入新事物会不会花费时间,甚至比遍历链表还要多?
如果以下陈述陈述了任何不正确的事实或假设,您能否更正一下。以除使用数组之外的任何其他方式使用向量(用于访问已存储数据之外的任何其他目的),意味着链表几乎总是更快,因为与链表不同,在向量中,您不仅会遍历元素,还会遍历它们,释放它们,然后创建一个全新的数组来容纳新空间。那是因为当前向量的最后一个元素之后的下一个地址可能有一个指针变量指向它,并且使用该地址会导致一种极其奇怪的行为,我无法想象可怜的灵魂试图找出问题所在的痛苦。”
TL;DR: 链表的缺点是遍历,但是向量的使用(push_back、resize() 等)通常都需要遍历,那么向量如何更快呢?
【问题讨论】:
-
将新事物插入
vector是摊销常数时间。有时会花费很多时间,但如果您插入N的东西,那么所花费的总时间将始终与N成正比。如果您必须每次(或大部分时间)“遍历”,那么它将与N²成正比,但事实并非如此。 -
(当然是在向量的末尾插入)。
-
vector用于替换旧的array的C的线性数据结构,而linked list用于非线性数据结构(即单链表或双链表)或树木等)。您将如何使用向量来表示有根的 b 树或在内存非常小的系统中管理数据的 I/O?如果您对大学项目或作业的要求只是将 POD 类型的数据仅存储在连续的内存块中,则可以使用您认为最合适或最喜欢的一个。