实验4:栈和队列的基本操作实现及其应用
一、实验目的
1、 熟练掌栈和队列的结构特点,掌握栈和队列的顺序存储和链式存储结构和实现。
2、 学会使用栈和队列解决实际问题。
二、实验内容
1、 自己确定结点的具体数据类型和问题规模:
分别建立一个顺序栈和链栈,实现栈的压栈和出栈操作。
分别建立一个顺序队列和链队列,实现队列的入队和出队操作。
2、 设计算法并写出代码,实现一个十将二进制转换成2进制数。
链队列的实现:
#include
using namespace std;
const int S=10;
struct Node{
int data;
Node * next;
};
class LinkQueue{
public:
LinkQueue(); //构造函数,初始化一个空的链队列
~LinkQueue();
void EnQueue(int x); //入队操作,将元素x入队
int DeQueue(); //出队操作,将队头元素出队
int GetQueue(){if(front!=rear) return front->next->data;} //取链队列的队头元素
int Empty(){if(front==rear) return 1;else return 0;} //判空
private:
Node *front,*rear; //队头和队尾指针,分别指向头结点和终端结点
};
LinkQueue::~LinkQueue()
{
Node *q;
while(front!=NULL)
{
q=front;
front=front->next;
delete q;
}
}
LinkQueue::LinkQueue()
{
Node *s;
s=new Node;s->next=NULL; //创建一个头结点
front=rear=s; //将队头指针和队尾指针都指向头结点
}
void LinkQueue::EnQueue(int x)
{
Node *s;
s=new Node;s->data=x;//申请一个数据域为x的结点s
s->next=NULL;
rear->next=s; //将结点s插入到队尾
rear=s;
}
int LinkQueue::DeQueue()
{
int x;
Node *p;
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 main()
{
int x,n,d,flag,tab;
LinkQueue Q;
flag=0;
do{
cout<<"输入你要的插入的数:"<>n;
cout<<"是否继续插入(1/0)"<>d;
Q.EnQueue(n);
}
while(d);
cout<>tab;
switch(tab)
{
case 1:{
cout<>x;
Q.EnQueue(x);
break;
}
case 2:
{
cout<
执行结果截图:
实验总结
通过这个实验,我认为,相对于前面学习的线性表,栈和队列的基本操作的实现要简单一些,实现顺序栈和链栈的所有基本操作的算法都只需要常数时间,循环队列和链队列也是如此。在空间性能方面,顺序栈有存储元素个数的限制和空间浪费的问题,链栈因指针域会产生结构性开销,当栈的使用过程元素的个数变化较大时,适宜用链栈,反之则用顺序栈。循环队列与链队列的空间性能比较与此类似。
在写链栈和链队列时,我的程序运行出现了同一个问题:程序什么问题也没有,错误显示 D:\个人文件\Dev-Cpp\collect2.exe [Error] ld returned 1 exit status ,在我不断检查程序后,发现把析构函数注释掉后,程序可正常运行,这说明是析构函数出了问题,经同学的指导后,发现析构函数不为空,在写了析构函数的算法后,程序可以正常运行了。这个问题说明我在写程序是不够细心,对书本的依赖太重,也说明我对以前所学知识的掌握不够熟悉,所以在学习新知识的同时,可以适当复习以前学过的C语言和C++的知识。