实验内容
1、自己确定结点的具体数据类型和问题规模:
分别建立一个顺序栈和链栈,实现栈的压栈和出栈操作。
分别建立一个顺序队列和链队列,实现队列的入队和出队操作。
一、顺序栈的定义与实现
#ifdef SeqStack_H //避免重复包含SeqStack.h头文件
#define SeqStack_H
const int StackSize=10; //栈最多有10个元素
template<class DateType> //定义模板类SeqStack
class SeqStack
{
public:
SeqStack(); //构造函数,栈的初始化
~SeqStack(){} //析构函数
void Push(DateType x); //将元素x入栈
DateType Pop(); //将栈顶元素弹出
DateType GetTop(); //取栈顶元素(并不删除)
int Empty(); //判断栈是否为空
private:
DateType date[StackSize]; //存放栈元素的数组
int top; //栈顶指针,指示栈顶元素在数组中的下标
};
#endif
#include"SeqStack.h" //引入类SeqStack的声明,以下是类SeqStack的成员函数定义
template<class DateType>
SeqStack<DateType>::SeqStack()
{
top=-1;
}
template<class DateType>
void SeqStack<DateType>::Push(DateType x)
{
if(top==StackSize-1) throw" 上溢";
top++;
date[top]=x;
}
template<class DateType>
DateType SeqStack<DateType>::Pop()
{
DateType x;
if(top==-1) throw"下溢 ";
x=date[top--];
return x;
}
template<class DateType>
DateType SeqStack<DateType>::GetTop()
{
if(top!=-1)
return date[top];
}
template<class DateType>
int SeqStack<DateType>::Empty()
{
if(top==-1) return 1;
else return 0;
}
#include<iostream> //引入输入输出流
using namespace std;
#include"SeqStack.cpp" //引入类SeqStack的成员函数定义,以下是主函数
void main()
{
SeqStack<int>S; //创建模板类的实例
if(S.Empty())
cout<<"栈为空"<<endl;
else
cout<<"栈非空"<<endl;
cout<<"对15和10执行入栈操作"<<endl;
S.Push(15);
S.Push(10);
cout<<"栈顶元素为:"<<endl; //取栈顶元素
cout<<S.GetTop()<<endl;
cout<<"执行一次出栈操作"<<endl;
S.Pop(); //执行出栈操作
cout<<"栈顶元素为:"<<endl;
cout<<S.GetTop()<<endl;
}
二、链栈的定义与实现
#include<iostream>
using namespace std;
template<class D> //定义模板类D
struct Node //定义结构体,用于结点的申请
{
D date;
Node<D> *next;
};
template<class D>
class SeqStack
{
Node<D> *top; //链栈的头指针
public:
SeqStack(){top=NULL;} //构造函数,初始化一个空链栈
~SeqStack() //析构函数,释放链栈中各节点的存储空间
{
while(top!=NULL) //释放链栈的每一个结点的存储空间
{
Node<D> *p=NULL;
p=top; //暂存被释放结点
top=top->next; //top指向被释放结点的下一个结点
delete p;
}
}
void Push(int x) //入栈操作,将元素x入栈
{
Node<D> *s;
s=new Node<D>; //申请一个数据域为x的结点s
s->date=x;
s->next=top;
top=s; //将栈顶s插入在栈顶
}
int Pop() //出栈操作,将栈顶元素出栈
{
Node<D> *p=NULL;
int x;
if(top==NULL) throw"下溢";
x=top->date;
p=top; //暂存栈顶元素
top=top->next; //将栈顶结点摘链
delete p;
return x;
}
int GetTop() //取栈顶元素(并不删除)
{
if(top!=NULL)
return top->date;
}
void Empty() //判空操作,判断链栈是否为空栈
{
top==NULL?cout<<"栈为空"<<endl:cout<<"栈非空"<<endl;
}
};
void main()
{
SeqStack<int> S;
S.Empty();
cout<<"对15和10执行入栈操作"<<endl;
S.Push(15);
S.Push(10);
cout<<"栈顶元素为:"<<endl; //取栈顶元素
cout<<S.GetTop()<<endl;
cout<<"执行一次出栈操作"<<endl;
S.Pop(); //执行出栈操作
cout<<"栈顶元素为:"<<endl;
cout<<S.GetTop()<<endl;
}
三、循环队列的定义与实现
#include<iostream>
using namespace std;
const int QueueSize=10;
class Linkqueue
{
int date[QueueSize]; //存放队列元素的数组
int front,rear; //队头和队尾指针
public:
Linkqueue(){front=rear=QueueSize-1;} //构造函数,初始化空队列
~Linkqueue(){} //析构函数为空
void Push(int x) //入队操作,将元素x入队
{
if((rear+1)%QueueSize==front) throw"上溢";
rear=(rear+1)%QueueSize; //队尾指针在循环意义下加一
date[rear]=x; //在队尾出插入元素
}
int Pop() //出队操作,将队头元素出队
{
if(rear==front) throw"下溢";
front=(front+1)%QueueSize; //队头指针在循环意义下加一
return date[front]; //读取并返回出队前的队头元素
}
int GetTop() //取队头元素(并不删除)
{
int i;
if(rear==front) throw"下溢";
i=(front+1)%QueueSize; //注意不要给队头指针赋值
return date[i];
}
int Empty() //判断队列是否为空
{
if(front=rear) return 1;
return 0;
}
};
void main()
{
Linkqueue S;
if(S.Empty())
cout<<"队列为空"<<endl;
else
cout<<"队列非空"<<endl;
cout<<"对15和10执行入栈操作"<<endl;
S.Push(15);
S.Push(10);
cout<<"查看队头元素为:"<<endl; //取栈顶元素
cout<<S.GetTop()<<endl;
cout<<"执行一次出队操作"<<endl;
S.Pop(); //执行出栈操作
cout<<"查看队头元素为:"<<endl;
cout<<S.GetTop()<<endl;
}
四、链队列的定义与实现
#include<iostream>
using namespace std;
template<class D> //定义模板类D
struct Node //定义结构体,用于结点的申请
{
D date;
Node<D> *next;
};
template<class D>
class Linkqueue
{
Node<D> *front,*rear; //队头与队尾指针
public:
Linkqueue() //构造函数,初始化一个空链队列
{
Node<D> *s;
s=new Node<D>;
s->next=NULL;
front=rear=s;
}
~Linkqueue() //析构函数,释放链队列中各节点的存储空间
{
while(front!=NULL) //释放链队列的每一个结点的存储空间
{
Node<D> *p=NULL;
p=front->next; //暂存被释放结点
delete front;
front=p;
}
}
void Push(int x) //入队操作,将元素x入队
{
Node<D> *s=NULL;
s=new Node<D>; //申请一个数据域为x的结点s
s->date=x;
s->next=NULL;
rear->next=s; //将s插入队尾
rear=s;
}
int Pop() //出队操作,将队头元素出队
{
Node<D> *p=NULL;
int x;
if(rear==front) throw"下溢";
p=front->next; //暂存队头元素
x=p->date;
front->next=p->next; //将队头结点摘链
if(p->next==NULL) rear=front; //判断出队前队列长度是否为1
delete p;
return x;
}
int GetTop() //取队头元素(并不删除)
{
if(front!=rear)
return front->next->date;
}
void Empty() //判空操作,判断链队列是否为空队列
{
front==rear?cout<<"队列为空"<<endl:cout<<"队列非空"<<endl;
}
};
void main()
{
Linkqueue<int> S;
S.Empty();
cout<<"对15和10执行入队操作"<<endl;
S.Push(15);
S.Push(10);
cout<<"查看队头元素为:"<<endl; //取队头元素
cout<<S.GetTop()<<endl;
cout<<"执行一次出队操作"<<endl;
S.Pop(); //执行出队操作
cout<<"查看队头元素为:"<<endl;
cout<<S.GetTop()<<endl;
}