Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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++ 基于数组的Deques:为什么AddFront/RemoveFront为O(1)?_C++_Queue_Dynamic Arrays_Deque - Fatal编程技术网

C++ 基于数组的Deques:为什么AddFront/RemoveFront为O(1)?

C++ 基于数组的Deques:为什么AddFront/RemoveFront为O(1)?,c++,queue,dynamic-arrays,deque,C++,Queue,Dynamic Arrays,Deque,对于基于阵列的deque,为什么从前面添加和删除弹药是O(1)?对我来说,它始终是O(n)是有意义的,因为任何一种操作都意味着数组的当前值需要“移动”到0索引的右侧进行添加,然后移动到左侧进行删除 我的教授说你不需要改变,只需要更新hi和lo。我不完全清楚他是什么意思 这不是一个C++问题本身,但我试图用这种语言理解它。 < p>你有2个指针(HI和LO),指向Deq的每个末端。 : 我不理解DEC++的精确C++实现,但这是我对你教授关于时间复杂度的合理化的最好尝试: 从和中,似乎数据是非连续

对于基于阵列的deque,为什么从前面添加和删除弹药是O(1)?对我来说,它始终是O(n)是有意义的,因为任何一种操作都意味着数组的当前值需要“移动”到0索引的右侧进行添加,然后移动到左侧进行删除

我的教授说你不需要改变,只需要更新hi和lo。我不完全清楚他是什么意思

<>这不是一个C++问题本身,但我试图用这种语言理解它。

< p>你有2个指针(HI和LO),指向Deq的每个末端。 :


我不理解DEC++的精确C++实现,但这是我对你教授关于时间复杂度的合理化的最好尝试:

从和中,似乎数据是非连续存储的

是另一个StackOverflow问题,它提供了有用的图像和一些丰富的信息

注意
start
是如何简单地指向前面的,但是也可以有
未使用的部分。因此,如果我们可以简单地将旧的正面标记为“未使用”,或者在背面标记为“未使用”,那么在弹出正面时可能不需要移动所有内容


编辑:我的猜测是,因为开头和结尾都有
未使用的
部分,所以添加到前面或后面相对比较容易,直到正如John在自己的回答中所说的,您的空间用完了/“命中边界”。

我假设它只是将指针移动到数组中的“前面”和“后面”不同位置。这会改变队列的逻辑结构,而不必在队列中的所有内容上来回移动。该死,我应该意识到它使用指针。好的,现在有道理了。但是,如果您添加到前端,您是否仍然需要移动/移动项目?是的,在添加时会发生移动,但仅当两端的空间用完时才会发生。假设您创建了此数据:{3,5,10,12},然后执行了五个addfronts。(不要担心尺寸/空间)。每个addfront是否意味着您必须进行转换,并且在每个addfront之后,lo将引用新值?这取决于具体情况。例如:您的数组足够大,可以容纳100个数字,示例中的3个位于
数组[50]
,12个位于
数组[53]
。那么你的5个addfronts就不需要任何移位了。@ohbrobig当你分配一个新的内存块时,你把旧的元素复制到块的中间而不是开始。然后,您可以在不移动的情况下添加到前面或后面,直到再次撞到边界。
std::deque
必须是非连续的,因为它对迭代器无效等有限制。在任意一端插入摊销O(1)并不是绝对必要的。我试图研究你所说的“迭代器失效”是什么意思,因为我不熟悉这个术语。根据我试图研究的内容,我假设这些“约束”是因为一个deque的特性(只能弹出/推前/推后)。这是真的吗?除此之外,我不明白为什么“迭代器失效约束”需要“非连续”存储。你能解释一下这个要求吗?我错了,迭代器可以在插入时失效,但引用不能。这意味着每个元素都需要保留在其原始内存位置,不能随着
deque
大小的增加而移动-这就是为什么它必须是非连续的。与
vector
相比,每当容器改变大小时,引用就会失效。有关规则,请参阅。感谢您提供的额外链接。我将继续研究您提供的要点[:
"aaaaa" <- hi
"bbbbb"
"ccccc"
"ddddd"<- lo
 //"aaaa" is still in the array but not considered part of the deque
 "bbbbb" <- hi
 "ccccc"
 "ddddd" <- lo
class Deque {
int deque[10];
int hi, lo;   // Initialize in constructor to -1 to flag deque is empty

public:
void push_front(int x) {
    // First time, add to middle of array
    if (-1 == lo) {
        hi = lo = 5; // Since array size is 10;
        deque[5] = x;
    }
    // Shift required?
    else if (lo == 0) {
        // Check if deque is full
        if (9 == hi) {
             // return error or get more space
        }
        else {
             // Shift by one
             // More optimally you would shift enough to move data to center of array
             for (int i = hi; i >= lo; --i) {
                 deque[i + 1] = deque[i];
             }
             // Update hi
             hi += 1;
             // Store in lo - lo remains at 0
             deque[0] = x;
         }
     }
     // No shift required
     else {
         deque[--lo] = x;
     }
 }
 // TODO: push_back, pop_front, pop_back