仅设尾指针的循环队列问题 不知道哪里错了 但好像思路没什么问题
输入一个整数序列:a
1
,a
2
,a
3
,…,a
n
,进行入队或出队操作。用带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意:不设头指针),试编写相应的置空队、判队空、入队和出队等算法,并实现以下任务:对输入的a
i
,当a
i
0时,将a
i
入队;当a
i
=0时,队头元素出队,若出队时队空则发生下溢“UNDERFLOW”,一旦发生下溢,则停止处理。
输入格式:
测试数据有多组,处理到文件尾。每组测试数据首先输入正整数n(n≤30),再输入n个整数。
输出格式:
对于每组测试,若处理过程中未发生下溢,则依次输出队列中当前还存在的元素(每两个数据之间留一个空格),否则输出“UNDERFLOW”表示下溢(若最终队列为空,也输出“UNDERFLOW”)。引号不必输出。
输入样例:
11 1 2 3 4 5 6 0 0 7 8 0
7 1 2 3 0 0 0 0
输出样例:
4 5 6 7 8
UNDERFLOW
```c++
#include<iostream>
using namespace std;
typedef int elemtype;
struct QNode{
elemtype data;
QNode *next;
};
struct LinkQueue{
QNode *rear;
void init();
void inqueue(elemtype e);
void outqueue();
bool empty();
void getFront();
};
void LinkQueue::init(){
rear=new QNode;
rear->next=rear;
}
void LinkQueue::inqueue(elemtype e){
QNode *p=new QNode;
p->data=e;
p->next=rear->next;
rear->next=p;
rear=p;
}
void LinkQueue::outqueue(){
if(rear==rear->next) return;
QNode *p=rear->next->next;
rear->next->next=p->next;
if(p==rear){
rear=rear->next;
}
delete p;
}
bool LinkQueue::empty(){
return rear=rear->next;
}
void solve(int n,int a[]){
LinkQueue que;
que.init();
for(int i=0;i<n;i++){
if(a[i]>0){
que.inqueue(a[i]);
}else if(que.empty()!=true&&a[i]==0){
que.outqueue();
}
}
if(que.empty()==true){
cout<<"UNDERFLOW"<<endl;
return;
}else{
int cnt=0;
cout<<1111;
for(int i=0;i<n;i++){
cnt++;
if(cnt!=1){
cout<<" ";
}
cout<<a[i];
}
}
}
int main(){
int n;
while(cin>>n){
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
solve(n,a);
}
}

#include<stdio.h>
#include<stdlib.h>
/**
* 链式循环队列结点结构体定义
*/
typedef struct CLNode {
/**
* 结点数据域,存储结点的数据值
*/
int data;
/**
* 结点指针域,存储当前结点的后继结点的地址
*/
struct CLNode *next;
/**
* 结点指针域,即队尾指针,指向队尾结点,存储队列尾结点的地址
*/
struct CLNode *rear;
} CLNode;
/**
* 初始化队列
* @param queue 未初始化的队列
*/
void init(CLNode **queue) {
// 创建头结点,queue 即为链式队列的头结点,为头结点分配空间
*queue = (CLNode *) malloc(sizeof(CLNode));
// 将链式队列头结点的 next 和 rear 指针都指向自身,因为是循环的,并且是空队列
(*queue)->next = *queue;
(*queue)->rear = *queue;
}
/**
* 将元素入队
* @param rear 循环链式队列的尾指针,指向链式队列的尾结点
* @param ele 待入队的元素
*/
void enQueue(CLNode **rear, int ele) {
// 1.创建新结点
// 1.1 为新结点分配存储空间
CLNode *newNode = (CLNode *) malloc(sizeof(CLNode));
// 1.2 为新结点指定数据域
newNode->data = ele;
// 1.2 为新结点指定指针域,新结点的指针域初始都指向 null
newNode->next = NULL;
// 2.将新结点入队
// 2.1 将新结点的 next 指针指向原队尾结点的后继结点。即将新结点与原队列头结点连接起来
// 实际上 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
newNode->next = (*rear)->next;
// 2.2 将原队尾结点的 next 指针指向新结点。即将原队列尾与新结点连接起来,才构成一个循环链
(*rear)->next = newNode;
// 2.3 将队尾指针指向新结点,即此时新结点成为了队列的队尾结点
(*rear) = newNode;
}
/**
* 将元素出队
* @param rear 循环链式队列的尾指针,指向链式队列的尾结点
* @param ele 保存出队的元素
* @return 如果出队成功则返回 1,否则返回 0 表示出队失败
*/
int deQueue(CLNode **rear, int *ele) {
// 0.参数校验,如果是空队列,则返回 0 表示不能出队。注意循环链表的判空条件
if ((*rear)->next == *rear) {
return 0;
}
// 其中 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
// 局部变量,头结点
CLNode *headNode = (*rear)->next;
// 局部变量,开始结点。而头结点的后继结点就是开始结点
CLNode *startNode = headNode->next;
// 1.用 ele 保存开始结点的数据域,因为队列是从队头出队,所以就是出队开始结点
*ele = startNode->data;
// 2.删除队头结点。即将队头结点的 next 指针指向原开始结点的后继结点
headNode->next = startNode->next;
// 如果元素出队后队列为空,则需要特殊处理
if (startNode==*rear){
*rear=(*rear)->next;
}
// 3.释放被删结点的空间
free(startNode);
// 4.返回 1 表示出队成功
return 1;
}
/**
* 打印循环链式队列
* @param queue 队列
*/
void print(CLNode *queue) {
printf("[");
CLNode *node = queue->next;
while (node != queue) {
printf("%d", node->data);
if (node->next != queue) {
printf(", ");
}
node = node->next;
}
printf("]\n");
}
int main() {
// 声明队列
CLNode *queue;
// 初始化队列
printf("\n初始化队列:\n");
init(&queue);
print(queue);
// 将元素入队
printf("\n将元素入队:\n");
// 这里传入的参数可能有点难以理解,因为 enQueue 方法的第一个参数是双指针,所以传入的是指针变量的地址
// queue是一个指针变量;&queue就是指针变量的地址,而queue->rear是为了获取队列的队尾指针,将队尾指针作为参数传入而非在函数内获取,是为了更直观了解函数的功能
enQueue(&(queue->rear), 11);
print(queue);
enQueue(&(queue->rear), 22);
print(queue);
enQueue(&(queue->rear), 33);
print(queue);
enQueue(&(queue->rear), 44);
print(queue);
enQueue(&(queue->rear), 55);
print(queue);
enQueue(&(queue->rear), 66);
print(queue);
// 将元素出队
printf("\n将元素出队:\n");
int ele;
deQueue(&(queue->rear), &ele);
printf("出队元素:%d\n", ele);
print(queue);
deQueue(&(queue->rear), &ele);
printf("出队元素:%d\n", ele);
print(queue);
deQueue(&(queue->rear), &ele);
printf("出队元素:%d\n", ele);
print(queue);
}