使用动态数组调整循环队列的大小
Resizing of the circular queue using dynamic array
我分析了下面的代码很长时间,但是,我仍然没有得到这个函数的一行,如下所示:
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;
}
}
我对上述代码的疑问是,在循环队列的动态数组实现中,在什么时候前面变得比后面更大?
原因是因为它是一个循环缓冲区。假设一个缓冲区的长度为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
所以"front"是读指针,接下来要读的东西。
"rear" 是写指针,最后插入的东西。
任何时候循环队列插入的元素超过 capacity
个,rear
环绕到开头,front > rear
变为真。该机制使它成为一个循环缓冲区。
如果在此之后调用此调整大小代码,它会将 front
读取指针之前的所有内容复制到末尾的新 space 中,并更新 rear
以指向该指针space.
(我认为如果它只复制元素到 rear
也是正确的。正如所写的那样,它正在复制陈旧的元素。)
我分析了下面的代码很长时间,但是,我仍然没有得到这个函数的一行,如下所示:
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;
}
}
我对上述代码的疑问是,在循环队列的动态数组实现中,在什么时候前面变得比后面更大?
原因是因为它是一个循环缓冲区。假设一个缓冲区的长度为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
所以"front"是读指针,接下来要读的东西。 "rear" 是写指针,最后插入的东西。
任何时候循环队列插入的元素超过 capacity
个,rear
环绕到开头,front > rear
变为真。该机制使它成为一个循环缓冲区。
如果在此之后调用此调整大小代码,它会将 front
读取指针之前的所有内容复制到末尾的新 space 中,并更新 rear
以指向该指针space.
(我认为如果它只复制元素到 rear
也是正确的。正如所写的那样,它正在复制陈旧的元素。)