我已经在分析以下代码很长时间了,但是仍然无法获得此函数的一行,如下所示:
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; """
}
}
我对上面的代码感到怀疑的是,在循环队列的动态数组实现的什么时候,前端变得比后端大?
答案 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
,这也是正确的。按照书面规定,它正在复制陈旧的元素。)