题目:
任务描述
本关任务:用带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(不设头指针)。实现该队列的入队出队以及判断队列是否为空操作。
编程要求
输入
多组数据,每组数据有两行。第一行为两个整数n和m,n表示入队序列A的长度(n个数依次连续入队,中间没有出队的情况),m表示出队序列B的元素数量(m个数依次连续出队,中间没有入队的情况)。第二行为序列A(空格分隔的n个整数)。当n和m都等于0时,输入结束。
输出
对应每组数据输出一行。每行包括m+1个整数,前m个数代表出队序列B的各个整数,最后一个整数表示队列是否为空,队列为空输出0,
测试说明
平台会对你编写的代码进行测试:
测试输入:
5 3
1 3 5 3 6
4 4
-1 2 3 4
0 0
预期输出:
1 3 5 1
-1 2 3 4 0
不为空输出1。整数之间用空格分隔。
解答
算法思想:
1.判断队空:
队列只有一个头结点,所以当头节点的指针域,指向自己的时候,队列就是空的;
2.入队操作:
新建一个结点,将新结点插入队列尾部,尾指针指向这个结点;
3:出队操作:
(1)当队列非空时,删除队头元素;
(2)当删除后队列为空时,一定要注意修改尾指针,指向头结点。
代码
#include<iostream>
using namespace std;
typedef struct QNode
{//队列的链式存储结构
int data;//数据域
struct QNode *next;//指针域
}QNode,*QueuePtr;
typedef struct
{
QueuePtr rear; //只设一个队尾指针
}LinkQueue;
QueuePtr p;//设置临时指针指向要插入/删除的结点
int EmptyQueue(LinkQueue Q)//判断队列是否为空,空返回1,否则返回0
{
return Q.rear->next->next==Q.rear->next;
}//队列只有一个头结点,即当头结点的指针域指向自己时,队列为空
void EnQueue(LinkQueue &Q,int e)//入队,插入元素e为Q的新的队尾元素
{
p=new QNode;//新建一个结点
p->data=e;//数据域赋值
p->next=Q.rear->next;//指向头结点(为循环队列,先保存头结点的地址)
Q.rear->next=p;//接着尾指针后面
Q.rear=p;//尾指针指向这个新结点
}
void DeQueue(LinkQueue &Q)//出队,输出Q的队头元素值,后将其删除
{
if(Q.rear->next->next==Q.rear->next)return ;//判断是否为空队列,是则结束
p=Q.rear->next->next;//p指向头结点的后面一个,p即队头指针
int e=p->data;//保存数据域元素
cout<<e<<" ";//输出删除的数据域元素
if(p==Q.rear)//如果删除的是最后一个元素,即删除后队列为空,则尾指针指向头结点
{
Q.rear=Q.rear->next;
Q.rear->next=p->next;//准备删除p(让头结点指向自己)
}else{
Q.rear->next->next=p->next;/*准备删除p(让头结点指向p(即要删除的结点 “队头结点” )后一个结点)*/
}
delete p;//释放结点
}
int main()
{
int n,m;
while(cin>>n>>m)//循环输入,当输入为0 0时退出
{
if(n==0&&m==0) break;
LinkQueue Q; //初始化一个带头结点的循环链表
Q.rear=new QNode;
Q.rear->next=Q.rear;//指向自己
while(n--)
{
int e;
cin>>e;
EnQueue(Q,e);//入队
}
while(m--)
DeQueue(Q);//出队
if(EmptyQueue(Q))//判断是否为空
cout<<"0"<<endl;
else
cout<<"1"<<endl;
}
return 0;
}
错误代码:
以上为正确代码,下面的代码有点问题,希望有大佬帮忙看看原因。在编译器输入的结果是对的,但在头歌上运行错误,不知道是什么原因。#include<iostream> using namespace std; typedef struct QNode {//队列的链式存储结构 int data; struct QNode *next; }QNode,*QueuePtr; typedef struct { QueuePtr rear; //只设一个队尾指针 }LinkQueue; int EmptyQueue(LinkQueue Q) {//判断队列是否为空,空返回1,否则返回0 //队列只有一个头结点,即当头结点的指针域指向自己时,队列为空 /**************begin************/ if(Q.rear->next==Q.rear->next->next)return 1; else return 0; /**************end************/ } void EnQueue(LinkQueue &Q,int e) {//入队,插入元素e为Q的新的队尾元素 /**************begin************/ QueuePtr p; p=new QNode; p->data=e; p->next=Q.rear->next; Q.rear->next=p; Q.rear=p; /**************end************/ } void DeQueue(LinkQueue &Q) {//出队,输出Q的队头元素值,后将其删除 /**************begin************/ QueuePtr p; p=(Q.rear->next->next); (Q.rear->next->next)=p->next; //cout<<" # "<<Q.rear<<" & "<<Q.rear->next<<" & "<<Q.rear->next->next<<" # "; cout<<p->data<<" "; delete p; /**************end************/ } int main() { int n,m; while(cin>>n>>m) { if(n==0&&m==0) break; LinkQueue Q; //初始化一个带头结点的循环链表 Q.rear=new QNode; Q.rear->next=Q.rear; while(n--) { int e;cin>>e; EnQueue(Q,e); } while(m--) DeQueue(Q); if(EmptyQueue(Q)) cout<<"0"<<endl; else cout<<"1"<<endl; } return 0; }