- 上述通过数组实现的循环队列申请的空间是固定的,在使用的过程中无法随时进行更改,这里希望通过动态数组的方式来实现循环队列;
- 需要特殊考虑的是加倍技术,也就是在队列使用过程中的动态扩容,参照栈的实现,需要使用
malloc
函数realloc
函数来实现,但是初始队列里面可能已经包含元素,所以这里需要考虑的是将元素需要进行复制; - 原始队列为满;
- 这里有一个位置是不填充元素的,首先将这个从下标
0
,也就是C
的位置进行展开
- 如果直接进行加倍并且进行元素的复制,得到的结果是
- 但是在保证队列里面元素相对位置不变的情况下,下面这种方式应该更好;
对于使用第二种方式进行复制的分析:
- 1.如果
front
的初始位置为0
,也就是说这个队列是一个满队列,这种情况下的复制就比较简单;
if (start < 2) { cout << start << endl; copy(Queue + 1, Queue + 1 + MAX_SIZE - 1, newQueue); }
- 2.否则对于数据的复制就分为两部分,首先是
front
部分的复制,然后是rear
部分的复制;
else { copy(Queue + start, Queue + start + MAX_SIZE, newQueue); copy(Queue, Queue + QueueInfo[0].rear + 1, newQueue + MAX_SIZE - start); }
- 1.如果
- 首先是队列初始化模块:
typedef struct
{
int key;
} elements;
typedef struct
{
int rear;
int front;
} Info;
int MAX_SIZE = 8;
Info QueueInfo[1];
void QueueInit( elements **Queue, Info *QueueInfo)
{
*Queue = (elements *)malloc(sizeof(elements) * MAX_SIZE);
if (Queue == NULL)
{
fprintf(stderr, "Malloc error\n");
exit(EXIT_FAILURE);
}
QueueInfo[0].rear = 0;
QueueInfo[0].front = 0;
}
- 然后是判断队列满了之后的处理:
elements *QueueFull(elements *Queue)
{
elements *newQueue;
newQueue = (elements *)malloc(2 * MAX_SIZE * sizeof(elements));
if (newQueue == NULL)
{
fprintf(stderr, "Malloc error\n");
exit(EXIT_FAILURE);
}
int start = (QueueInfo[0].front + 1) % MAX_SIZE;
if (start < 2)
{
cout << start << endl;
copy(Queue + 1, Queue + 1 + MAX_SIZE - 1, newQueue);
}
else
{
copy(Queue + start, Queue + start + MAX_SIZE, newQueue);
copy(Queue, Queue + QueueInfo[0].rear + 1, newQueue + MAX_SIZE - start);
}
QueueInfo[0].front = 2 * MAX_SIZE - 1;
QueueInfo[0].rear = MAX_SIZE - 1;
for (int i = 0; i < MAX_SIZE; i++)
{
cout << Queue[i].key << " ";
}
cout << endl;
MAX_SIZE *= 2;
free(Queue);
Queue = newQueue;
return Queue;
}
- 然后是添加元素,并可能调用上面的函数
elements *AddQ(elements *Queue, int data)
{
QueueInfo[0].rear = (QueueInfo[0].rear + 1) % MAX_SIZE;
if (QueueInfo[0].front == QueueInfo[0].rear)
Queue = QueueFull(Queue);
Queue[QueueInfo[0].rear].key = data;
return Queue;
}
elements DeleteQ(elements *Queue)
{
if (QueueInfo[0].rear == QueueInfo[0].front)
{
fprintf(stderr, "The Queue is empty\n");
exit(EXIT_FAILURE);
}
QueueInfo[0].front = (QueueInfo[0].front + 1) % MAX_SIZE;
return Queue[QueueInfo[0].front];
}
- 然后是判断队列是否为满
int IsFull()
{
return (QueueInfo[0].rear + 1) % MAX_SIZE == QueueInfo[0].front ?
true : false;
}
- 判断是否为空
int IsEmpty(){
return (QueueInfo[0].front%MAX_SIZE==QueueInfo[0].rear) ?
true : false;
}
上面的参数都进行了返回值的接收,因为是传值调用,因为这个是C++文件,也是可以改成引用传递的
* 完整的代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#define true 1
#define false 0
using namespace std;
typedef struct
{
int key;
} elements;
typedef struct
{
int rear;
int front;
} Info;
int MAX_SIZE = 8;
Info QueueInfo[1];
elements *QueueFull(elements *Queue)
{
elements *newQueue;
newQueue = (elements *)malloc(2 * MAX_SIZE * sizeof(elements));
if (newQueue == NULL)
{
fprintf(stderr, "Malloc error\n");
exit(EXIT_FAILURE);
}
int start = (QueueInfo[0].front + 1) % MAX_SIZE;
if (start < 2)
{
cout << start << endl;
copy(Queue + 1, Queue + 1 + MAX_SIZE - 1, newQueue);
}
else
{
copy(Queue + start, Queue + start + MAX_SIZE, newQueue);
copy(Queue, Queue + QueueInfo[0].rear + 1, newQueue + MAX_SIZE - start);
}
QueueInfo[0].front = 2 * MAX_SIZE - 1;
QueueInfo[0].rear = MAX_SIZE - 1;
for (int i = 0; i < MAX_SIZE; i++)
{
cout << Queue[i].key << " ";
}
cout << endl;
MAX_SIZE *= 2;
free(Queue);
Queue = newQueue;
return Queue;
}
void QueueInit( elements **Queue, Info *QueueInfo)
{
*Queue = (elements *)malloc(sizeof(elements) * MAX_SIZE);
if (Queue == NULL)
{
fprintf(stderr, "Malloc error\n");
exit(EXIT_FAILURE);
}
QueueInfo[0].rear = 0;
QueueInfo[0].front = 0;
}
elements *AddQ(elements *Queue, int data)
{
QueueInfo[0].rear = (QueueInfo[0].rear + 1) % MAX_SIZE;
if (QueueInfo[0].front == QueueInfo[0].rear)
Queue = QueueFull(Queue);
Queue[QueueInfo[0].rear].key = data;
return Queue;
}
elements DeleteQ(elements *Queue)
{
if (QueueInfo[0].rear == QueueInfo[0].front)
{
fprintf(stderr, "The Queue is empty\n");
exit(EXIT_FAILURE);
}
QueueInfo[0].front = (QueueInfo[0].front + 1) % MAX_SIZE;
return Queue[QueueInfo[0].front];
}
int IsFull()
{
return (QueueInfo[0].rear + 1) % MAX_SIZE == QueueInfo[0].front ?
true : false;
}
int IsEmpty(){
return (QueueInfo[0].front%MAX_SIZE==QueueInfo[0].rear) ?
true : false;
}
int main()
{
elements *Queue = NULL;
QueueInit(&Queue, QueueInfo);
AddQ(Queue, 10);
AddQ(Queue, 9);
AddQ(Queue, 8);
AddQ(Queue, 7);
AddQ(Queue, 6);
AddQ(Queue, 5);
Queue = AddQ(Queue, 4);
cout << IsFull() << endl;
cout << IsEmpty() << endl;
// Queue = AddQ(Queue, 3);
// AddQ(Queue, 2);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// cout << "My Queue Delete " << endl;
// cout << "MAX_SIZE " << MAX_SIZE << endl;
// DeleteQ(Queue);
// DeleteQ(Queue);
// DeleteQ(Queue);
// DeleteQ(Queue);
// DeleteQ(Queue);
// DeleteQ(Queue);
// DeleteQ(Queue);
// DeleteQ(Queue);
// DeleteQ(Queue);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
// AddQ(Queue, 1);
cout << "My Queue contains:\n" << endl;
for (int i = 0; i < MAX_SIZE; i++)
{
cout << Queue[i].key << " ";
}
return 0;
}