数据结构实验三
实验3:队列的链式表示和实现
要求:构建2个用带头结点的单链表队列QA和QB, 实现下列操作
1、初始化队列(清空);
2、入队;
3、出队;
4、求队列长度;
5、判断队列是否为空;
6、对于队列QA和QB,如果其中一个队列的售货员下班,则自动甩到另一个队列后面。
链式队列的初始化:
(别问我为什么把Front 和 rear 定义在结构体里,可能是因为B格比较高趴,其实你可以直接定义在外面)
typedef struct Qnode
{
int data;
struct Qnode *next;
} Qnode, *Queueptr;
typedef struct
{
Queueptr Front;
Queueptr rear;
} Linqueue;
void Creat(Linqueue &Q)//初始化
{
Q.Front = Q.rear = MALL;
Q.Front->next = NULL;
}
入队操作(单个元素入队)
int Enqueue(Linqueue &Q, int e)//入队,其实这个就是单链表的前插 法,当然, 你也可以while(n--)
{
Queueptr p;
p = MALL;
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return 1;
}
出队和清空:
void Dequeue(Linqueue &Q)//全部出队
{
if(Q.Front == Q.rear)
cout << "该队列目前为空" << '\n';
else
{
Queueptr p = Q.Front->next;
Queueptr q;
while(p != Q.rear)
{
cout << p->data << ' ';
Q.Front->next = p->next;
q = p;
p = p->next;
free(q);
}
Q.rear = Q.Front;
cout << p->data << '\n';
free(p);
}
cout << '\n';
}
int Delete(Linqueue &Q)//清空队列,和出队差不多
{
if(Q.Front == Q.rear)
return 0;
Queueptr p = Q.Front->next, q;
while(p != Q.rear)
{
Q.Front->next = p->next;
q = p;
p = p->next;
free(q);
}
Q.rear = Q.Front;
free(p);
return 1;
}
你会发现,差不多趴。。。。。。
将队列L接到队列Q的末尾:
(核心代码)
void connect(Linqueue &Q, Linqueue &L)
{
Q.rear->next = L.Front->next;
Q.rear = L.rear;
}
全凭自己参悟,可能代码不够精简,有空修改,如有更好建议,请在评论区毫不留情的纠正我,谢谢拉!!!,(以后有空就缩减下吧!看着长难受,),下面给出完整版的实验三代码:
//#include<bits/stdc++.h>
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stdlib.h>
#include<cstring>
#include<string.h>
#include<string>
#include<math.h>
using namespace std ;
typedef long long ll;
#define MAXN 100005
#define INF 0x3f3f3f3f
#define MALL (Qnode *)malloc(sizeof(Qnode));
typedef struct Qnode//单链表
{
int data;
struct Qnode *next;
} Qnode, *Queueptr;
typedef struct//头尾指针
{
Queueptr Front;
Queueptr rear;
} Linqueue;
void Creat(Linqueue &Q)//初始化
{
Q.Front = Q.rear = MALL;
Q.Front->next = NULL;
}
int Enqueue(Linqueue &Q, int e)//一个元素一个元素的入队,当然, 你可以读入n
{
Queueptr p;
p = MALL;
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return 1;
}
void Dequeue(Linqueue &Q)//全部出队,
{
if(Q.Front == Q.rear)
cout << "该队列目前为空" << '\n';
else
{
Queueptr p = Q.Front->next;
Queueptr q;
while(p != Q.rear)
{
cout << p->data << ' ';
Q.Front->next = p->next;
q = p;
p = p->next;
free(q);
}
Q.rear = Q.Front;
cout << p->data << '\n';
free(p);
}
cout << '\n';
}
int Delete(Linqueue &Q)//清空队列,和出队差不多,就是没有输出数据
{
if(Q.Front == Q.rear)
return 0;
Queueptr p = Q.Front->next, q;
while(p != Q.rear)
{
Q.Front->next = p->next;
q = p;
p = p->next;
free(q);
}
Q.rear = Q.Front;
free(p);
return 1;
}
void len(Linqueue Q)//求此时队列的长度
{
int le = 0;
while(Q.Front != Q.rear)
{
Q.Front = Q.Front->next;
le++;
}
if(le == 0)
cout << "该队列目前为空" << '\n';
else
cout << "目前队列的长度为:" << le << '\n';
}
void connect(Linqueue &Q, Linqueue &L)//连接A,B两个队列
{
Q.rear->next = L.Front->next;
Q.rear = L.rear;
}
int main()
{
cout << "请开始你的链式队列操作之旅:" << '\n';
cout << "已经为您初始化了A、B队列" << '\n';
Linqueue a, b, ss, mm;
Creat(a);
Creat(b);
while(1)//这里我用了if,,,太冗余了代码,但是复制完之后就不想改了,orzzzz。。。
{
cout << "请选择对A或B队列进行简易操作:" << '\n';
char ch, sh;
int c;
cin >> ch;
cout << "请选择要进行的操作:" << '\n';
cout << "1、清空" << ch << "队" << '\n';
cout << "2、入队(输入为-1时结束入队)" << '\n';
cout << "3、出队(全部出队)" << '\n';
cout << "4、求队列长度" << '\n';
cout << "5、让" << ch << "下班, 并输出仅剩的唯一序列(注:A、B队列为空时无法执行,待修复)" << '\n';
cout << "6、退出操作" << '\n';
if(ch == 'A')
{
cin >> c;
switch(c)
{
case 1: Delete(a); break;
case 2: int d;
while(scanf("%d", &d) && d!=-1)
Enqueue(a, d);
break;
case 3: Dequeue(a); break;
case 4: len(a); break;
case 5: connect(b, a); Dequeue(b); break;
}
if(c == 6) break;
}
else
{
cin >> c;
switch(c)
{
case 1: Delete(b); break;
case 2: int d;
while(scanf("%d", &d) && d!=-1)
Enqueue(b, d);
break;
case 3: Dequeue(b); break;
case 4: len(b); break;
case 5: connect(a, b); Dequeue(a); break;
}
if(c == 6) break;
}
system("pause");
system("cls");
}
return 0;
}