使用动态数组调整循环队列的大小

时间:2019-03-25 17:43:50

标签: c arrays queue dynamic-arrays

我已经在分析以下代码很长时间了,但是仍然无法获得此函数的一行,如下所示:

void ResizeQueue(struct DynArrayQueue* q) {

    int size = q->capacity;
    q->capactiy = q->capacity*2;
    q->array = realloc(q->array,q->capacity);
    if(!q->array) {
        printf("Memory error");
        return;
    }
    """(the doubt lines):

        if(q->front > q->rear) {
        for(int i = 0; i<q->front; i++) {
            q->array[i+size] = q->array[i];
        }
        q->rear = q->rear + size; """
   }
   }

我对上面的代码感到怀疑的是,在循环队列的动态数组实现的什么时候,前端变得比后端大?

2 个答案:

答案 0 :(得分:1)

原因是因为它是循环缓冲区。假设缓冲区的长度为8,这是两个场景A和B,其中缓冲区中有4个数据项,使用-指示无关数据,使用d指示缓冲数据:

index   0   1   2   3   4   5   6   7

A data  -   d   d   d   d   -   -   -
          begin        end

B data  d   d   -   -   -   -   d   d
           end                begin

因此,由于-根据循环缓冲区的定义-数据自动换行,因此头部可能低于尾部,或者尾部可能低于头部。

看看缓冲区B的长度加倍时会发生什么

index   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
B data  d   d   -   -   -   -   d   d   -   -   -   -   -   -   -   -
           end                begin

现在应该很清楚为什么需要移动数据,就像这样:

index   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
B data  d   d   -   -   -   -   -   -   -   -   -   -   -   -   d   d
           end                                                begin

相应调整了指针或索引。

或者可以将数据调整为如下所示:

index   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
B data  -   -   -   -   -   -   d   d   d   d   -   -   -   -   -   -
                              begin        end

答案 1 :(得分:0)

因此,“前”是读取指针,即下一个要读取的内容。 “后方”是写指针,是最后插入的东西。

每当循环队列中插入的元素超过capacity个时,rear就会绕到开头,并且front > rear变为true。这种机制使它成为循环缓冲区。

如果在此之后调用此调整大小代码,则会将front读指针之前的所有内容复制到最后的新空间,并更新rear指向该空间。

(我认为,如果仅将元素复制到rear,这也是正确的。按照书面规定,它正在复制陈旧的元素。)