循环队列的动态回收方法很简单,我刚开始有两个实现思路,一种是利用链表,每生成一个结点就能增加一个空间,但是查找太麻烦了。数组的话会更方便一些。总的来说,就是用一个指针实现动态分配内存,如果空间不够那就直接分配一个更大的空间,把原来的数据全部移到这个新的空间里,把原来队列的空间释放掉。同理,回收空间也是这样的。话不多说直接附上代码
#include <iostream>
#include <string>
#include<iomanip>
using namespace std;
# define QUEUE_INIT_SIZE 5 //队列存储空间的初始分配量
# define QUEUE_INCREMENT 5 //队列存储空间的分配增量
# define QUEUE_FREESIZE 10 //队列存储空间的回收预定值
# define PERCENT 0.5 //队列闲置空间的回收比例
typedef string ElementType; // 假设队列存储的是整数类型
// 循环队列的结构定义
typedef struct {
ElementType* element; // 存储队列元素的数组
int front; // 队头指针
int rear; // 队尾指针
int QueueSize; // 队列当前的最大长度
int length; // 队列的使用长度
} SeqQueue;
// 初始化队列
void InitQueue(SeqQueue& Q) {
Q.element = new ElementType[QUEUE_INIT_SIZE];
Q.front = Q.rear = 0;
Q.length = 0;
Q.QueueSize = QUEUE_INIT_SIZE;
}
//队列重置
void ReInitQueue(SeqQueue &Q) {
delete[] Q.element;
Q.element = new ElementType[QUEUE_INIT_SIZE];
Q.rear = Q.front = 0;
Q.length = 0;
Q.QueueSize = QUEUE_INIT_SIZE;
}
//判断队满
bool full(SeqQueue &Q) {
if (Q.length == Q.QueueSize)return true;
else return false;
}
bool empty(SeqQueue& Q) {
if (Q.length==0)return true;
else return false;
}
// 回收空闲空间
void RecycleSpace(SeqQueue& Q) {
if (Q.QueueSize - Q.length >= Q.QueueSize*PERCENT) {
int newSize = int(Q.QueueSize * PERCENT);
ElementType* newElement = new ElementType[newSize];
int j = Q.front;
int i = 0;
while (i < Q.length) {
newElement[i] = Q.element[j];
i++;
j = (j + 1) % Q.QueueSize;
}
delete[] Q.element;
Q.element = newElement;
Q.front = 0;
Q.rear = i;
Q.QueueSize = newSize;
cout << "回收空间成功!" << endl;
}
else cout << "队列剩余空间不超过总空间的一半,回收失败!"<<endl;
}
// 增加空间
void IncreaseSpace(SeqQueue& Q) {
int newSize = Q.QueueSize + QUEUE_INCREMENT;
ElementType* newElement = new ElementType[newSize];
int j = Q.front;
int i = 0;
while (i< Q.length ) {
newElement[i] = Q.element[j];
i++;
j = (j + 1) % Q.QueueSize;
}
delete[] Q.element;
Q.element = newElement;
Q.front = 0;
Q.rear = i;
Q.QueueSize = newSize;
}
// 入队
void EnQueue(SeqQueue& Q, ElementType x) {
if (full(Q)) {
// 队列已满,需要增加空间
cout << "队列已满,自动增加空间"<<endl;
IncreaseSpace(Q);
}
Q.element[Q.rear] = x;
Q.rear = (Q.rear + 1) % Q.QueueSize;
Q.length++;
}
// 出队
void DeQueue(SeqQueue& Q,ElementType &x) {
if (empty(Q)) {
// 队列为空,无法出队
cout << "\t\t\t队列为空,无法出队\t\t\t" << endl;
return ;
}
x=Q.element[Q.front];
Q.front = (Q.front + 1) % Q.QueueSize;
Q.length--;
cout << "出队的元素为:" << x << endl;
}
//查看队列元素
void skim(SeqQueue &Q) {
int i,j=0;
if (empty(Q)) {
cout << "\t\t\t队列为空,无法出队\t\t\t"<<endl;
return;
}
i = Q.front;
cout << "\t\t\t队列元素为:";
while (j < Q.length) {
cout<<Q.element[i]<<" ";
i = (i + 1) % Q.QueueSize;
j++;
}
cout << endl;
}
//菜单
void menu() {
cout << "\t\t|-----------------------------------------------|"<<endl;
cout << "\t\t|\t1.入队\t\t\t\t\t|" << endl << "\t\t|\t2.出队\t\t\t\t\t|" << endl << "\t\t|\t3.查看队列元素\t\t\t\t|" <<endl<< "\t\t|\t4.重置队列(回到最初设置)\t\t|\t" << endl << "\t\t|\t5.增加空间\t\t\t\t|" << endl << "\t\t|\t6.回收空间\t\t\t\t|" <<endl<< "\t\t|\t0.退出程序\t\t\t\t|"<<endl;
cout << "\t\t|-----------------------------------------------|" << endl;
cout << "\t\t\t请选择操作:";
}
// 销毁队列
void DestroyQueue(SeqQueue& Q) {
delete[] Q.element;
Q.front = Q.rear = 0;
Q.QueueSize = 0;
}
//主函数
int main() {
SeqQueue Q;
InitQueue(Q);
int choice,n,i;
ElementType x;
float a;
do {
a = float(Q.length)/Q.QueueSize;
cout << "\t\t|\t当前队列使用存储空间情况:"<< fixed << setprecision(3) << a << "\t\t|\t" << endl;
if (a <= 0.5)cout << "\t\t|\t当前队列使用空间小于0.5可选择回收空间\t|\t\t" << endl;
cout << "\t\t|\t队列长度为:" << Q.length << "\t\t\t\t|" << endl;
cout << "\t\t|\t队列空间为:" << Q.QueueSize << "\t\t\t\t|" << endl;
cout << "\t\t|\t剩余空间:" << Q.QueueSize-Q.length << "\t\t\t\t|" << endl;
menu();
cin >> choice;
switch (choice) {
case 1:
cout << "请输入有多少元素入队:";
cin >> n;
for (i = 1; i <= n; i++) {
cout << "请输入要入队的元素:";
cin >> x;
EnQueue(Q, x);
}
a = float(Q.length) / Q.QueueSize;
if (a <= 0.5)RecycleSpace(Q);
break;
case 2:
cout << "请输入要出队多少元素:";
cin >> n;
for (i = 1; i <= n; i++) {
DeQueue(Q, x);
a = float(Q.length) / Q.QueueSize;
if (a <= 0.5)RecycleSpace(Q);
}
break;
case 3:
skim(Q);
break;
case 4:
ReInitQueue(Q);
cout << "重置成功!";
break;
case 5:
IncreaseSpace(Q);
cout << "增加空间成功!" << endl;
break;
case 6:
RecycleSpace(Q);
break;
case 0:
break;
default:
cout << "选择错误,请重新选择!" << endl; break;
}
system("pause");
system("cls");
} while (choice != 0);
DestroyQueue(Q);
return 0;
}