实验项目名称:队列的算法实现及应用
实验目的:熟悉队列的逻辑特性、存储表示方法和队列基本操作及应用。
实验要求:了解并熟悉队列的逻辑特性、顺序和链式存储表示方法和队列的基本操作的实现和应用。
实验内容
编写程序实现下列的要求:
(1)编写程序,用不同的存储方法,实现队列的基本操作。
循环队列(顺序):
#include<iostream>
using namespace std;
//循环队列(顺序)
const int QueueSize = 100; //100是示例性数据
class CirQueue
{
public:
CirQueue(); //构造函数,初始化空队列
~CirQueue(); //析构函数
void EnQueue(int x); //入队操作,将元素x入队
int DeQueue(); //出队操作,将队头元素出队
int GetHead(); //取队头元元素(并不删除)
int Empty(); //判断队列是否为空
private:
int data[QueueSize]; //存放队列元素的数组
int front, rear; //游标,对头和队尾指针
};
CirQueue::CirQueue() //循环队列构造函数
{
rear = front = QueueSize - 1;
}
CirQueue::~CirQueue() //循环队列的析构函数
{
}
void CirQueue::EnQueue(int x) //循环队列的入队操作
{
if((rear + 1) % QueueSize == front)throw"上溢";
rear = (rear + 1) % QueueSize; //队尾指针在循环意义下加1
data[rear] = x; //在队尾处插入元素
}
int CirQueue::DeQueue() //出队操作
{
if(rear == front)
throw"下溢";
front = (front + 1) % QueueSize; //队头在循环意义下加1
return data[front]; //返回出队前的队头元素
}
int CirQueue::GetHead() //取队头元素
{
if(rear == front) throw"下溢";
return data[(front + 1) % QueueSize]; //注意不修改队头指针
}
int CirQueue::Empty() //判空操作
{
if(rear == front)
cout << "当前队列为空" << endl;
else
cout << "当前队列非空" << endl;
}
int main() {
int n, x;
cout << "请输入队列长度";
cin >> n;
CirQueue q; //定义对象变量Q
cout << "请依次输入入队元素:" << endl;
for(int i = 0; i < n; i++) {
int t;
cin >> t;
q.EnQueue(t);
}
q.Empty();
cout << "请输入入队元素:";
cin >> x;
q.EnQueue(x);
cout << "执行一次出队操作,出队元素是:" << q.DeQueue() << endl;
q.DeQueue();
}
链式:
#include <iostream>
using namespace std;
//链队列
struct Node
{
int data; //数据域
Node *next; //指针域
};
class LinkQueue
{
public:
LinkQueue( ); //构造函数,初始化一个空的链队列
~LinkQueue( ); //析构函数,释放链队列各结点的存储空间
void EnQueue(int x); //入队操作,将元素x入队
int DeQueue( ); //出队操作,将队头元素出队
int GetQueue( ); //取链队列的队头元素
int Empty( ); //判断链队列是否为空
void PrintQueue( ); //遍历链队列操作
private:
Node *front, *rear; //队头和队尾指针,分别指向头结点和终端结点
};
LinkQueue :: LinkQueue( ) //构造函数,初始化一个空的链队列
{
Node *s = NULL;
s = new Node; s->next = NULL; //创建头结点s
front = rear = s; //将队头指针和队尾指针都指向头结点s
}
LinkQueue :: ~LinkQueue() //析构函数,释放链队列各结点的存储空间
{
Node *q = NULL;
while (front != NULL) //释放单链表的每一个结点的存储空间
{
q = front; //暂存被释放结点
front = front->next; // front指向被释放结点的下一个结点
delete q;
}
}
void LinkQueue :: EnQueue(int x) //入队操作,将元素x入队
{
Node *s = NULL;
s = new Node; //申请结点s
s->data = x; s->next = NULL;
rear->next = s; rear = s; //将结点s插入到队尾
}
int LinkQueue :: DeQueue( ) //出队操作,将队头元素出队
{
int x;
Node *p = NULL;
if (rear == front) throw "下溢";
p = front->next; x = p->data; //暂存队头元素
front->next = p->next; //将队头元素所在结点摘链
if (p->next == NULL) rear = front; //判断出队前队列长度是否为1
delete p;
return x;
}
int LinkQueue :: GetQueue() //取链队列的队头元素
{
if(front == rear)
throw "下溢异常";
else
return front->next->data;
}
int LinkQueue :: Empty() //判断链队列是否为空
{
if(front == rear)
cout << "当前队列:为空" << endl;
else
cout << "当前队列:非空" << endl;
}
void LinkQueue::PrintQueue() //遍历链队列操作
{
Node *p = front->next; //工作指针p初始化
while(p != NULL) {
cout << p->data << " ";
p = p->next; //工作指针p后移,注意不能写作p++
}
cout << endl;
}
int main( )
{
int n, x;
cout << "请输入定义的链队列长度";
cin >> n;
LinkQueue Q; //定义对象变量Q
cout << "请依次输入入队元素:" << endl;
for(int i = 0; i < n; i++)
{
int t;
cin >> t;
Q.EnQueue(t);
}
Q.Empty();
cout << "当前链队列遍历为:" << endl;
Q.PrintQueue();
cout << "当前链队列队头元素为:" << Q.GetQueue( ) << endl; //输出队头元素
cout << "执行一次出队操作,出队元素是:" << Q.DeQueue( ) << endl; //输出出队元素
cout << "请输入入队元素:";
cin >> x;
Q.EnQueue(x);
Q.Empty();
cout << "当前链队列队头元素为:" << Q.GetQueue( ) << endl; //输出队头元素
cout << "当前链队列遍历为:" << endl;
Q.PrintQueue();
return 0;
}
(2)*迷宫问题:求解m*n迷宫问题,输出解的个数及每个解。编写并实现它的算法。