Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在O(1)(摊销)中,我将如何执行此任务?_C++_Algorithm_Big O - Fatal编程技术网

C++ 在O(1)(摊销)中,我将如何执行此任务?

C++ 在O(1)(摊销)中,我将如何执行此任务?,c++,algorithm,big-o,C++,Algorithm,Big O,在我继续之前,我只是想和某人确认一下,我已经走上了正确的道路。问题是,当我想向已经满的数组中添加新元素时,我必须“在O(1)(摊销)中扩展数组” 这是否意味着每次我在完整列表中插入新元素时,我应该添加5个元素或类似的内容,这样我就不必在每次添加新元素时执行扩展 当然,这可能取决于您的编译器/操作系统,但标准是: 1. Allocate a new buffer with size 50 percent larger than the current buffer size 2. Copy the

在我继续之前,我只是想和某人确认一下,我已经走上了正确的道路。问题是,当我想向已经满的数组中添加新元素时,我必须“在O(1)(摊销)中扩展数组”


这是否意味着每次我在完整列表中插入新元素时,我应该添加5个元素或类似的内容,这样我就不必在每次添加新元素时执行扩展

当然,这可能取决于您的编译器/操作系统,但标准是:

1. Allocate a new buffer with size 50 percent larger than the current buffer size
2. Copy the data from the current buffer to the new buffer.
3. Perhaps fiddle with addresses so the new buffer replaces the old buffer.  

因此这需要O(1)

当然,这可能取决于编译器/OS,但标准是:

1. Allocate a new buffer with size 50 percent larger than the current buffer size
2. Copy the data from the current buffer to the new buffer.
3. Perhaps fiddle with addresses so the new buffer replaces the old buffer.  
这需要O(1)

这是否意味着每次我在完整列表中插入新元素时,我应该添加5个元素或类似的内容,这样我就不必在每次添加新元素时执行扩展

有点。但是任何数量不变的额外插槽都会有相同的问题:即使您只需要每五次插入就复制到一个新数组,每次插入的平均时间仍然是O(n),因为O(n/5)=O(n)

相反,您需要添加与阵列的当前大小成比例的插槽数量。最简单的方法是在需要增长时将数组大小加倍,平均为O(n/n)=O(1);但是增加50%或者任何其他不变的比例,都会产生同样的效果

这是否意味着每次我在完整列表中插入新元素时,我应该添加5个元素或类似的内容,这样我就不必在每次添加新元素时执行扩展

有点。但是任何数量不变的额外插槽都会有相同的问题:即使您只需要每五次插入就复制到一个新数组,每次插入的平均时间仍然是O(n),因为O(n/5)=O(n)


相反,您需要添加与阵列的当前大小成比例的插槽数量。最简单的方法是在需要增长时将数组大小加倍,平均为O(n/n)=O(1);但是增加50%或任何其他固定比例都会产生同样的效果。

是的,这是基本想法。假设扩展数组只是一个持续的惩罚,那将是
O(1)
。太好了,谢谢你的帮助。@TimBiegeleisen:你的意思是不,对吗?基本思想是按与当前大小成比例的数量增加大小,而不是像OP建议的那样,以恒定数量的元素增加大小。是的,这是基本思想。假设扩展数组只是一个持续的惩罚,那将是
O(1)
。太好了,谢谢你的帮助。@TimBiegeleisen:你的意思是不,对吗?基本思想是按与当前大小成比例的数量增加大小,而不是像OP所建议的那样增加常量元素。你的第2步是O(N)。@selbie--是的,算法的这一部分是O(N),但不是每次都这样做;每N次插入都会执行一次(松散地说),这就是为什么追加的总体复杂性是O(1)摊销的原因。例如,这就是
std::vector
使用的方法。哦,我明白了。。。谢谢你的步骤#2是O(N)。@selbie——是的,算法的那部分是O(N),但不是每次都这样;每N次插入都会执行一次(松散地说),这就是为什么追加的总体复杂性是O(1)摊销的原因。例如,这就是
std::vector
使用的方法。哦,我明白了。。。谢谢请注意,加倍会导致移动向量问题。假设您从用于阵列的1k开始。然后分配2k,复制,并将前1k返回堆。接下来,分配4k,然后返回2k。现在有3k空闲,4k使用。下一个循环7k空闲,8k使用。免费存储空间永远不会足够大,无法回收用于新分配,因此进程的总内存是实际使用内存的2倍!如果你使用1.5,在几个周期后,你释放的东西足够大以适应下一次分配。请注意,加倍会导致一个旅行向量问题。假设您从用于阵列的1k开始。然后分配2k,复制,并将前1k返回堆。接下来,分配4k,然后返回2k。现在有3k空闲,4k使用。下一个循环7k空闲,8k使用。免费存储空间永远不会足够大,无法回收用于新分配,因此进程的总内存是实际使用内存的2倍!如果使用1.5,经过几个周期后,您释放的内容足够大,可以适应下一次分配。