信管1172潘連香資料結構實驗二1
實驗內容
1、自己確定結點的具體資料型別和問題規模:
分別建立一個順序棧和鏈棧,實現棧的壓棧和出棧操作。
分別建立一個順序佇列和鏈佇列,實現佇列的入隊和出隊操作。
一、順序棧的定義與實現
#ifdef SeqStack_H //避免重複包含SeqStack.h標頭檔案
#define SeqStack_H
const int StackSize=10; //棧最多有10個元素
template<class DateType> //定義模板類
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;
}