利用两种不同的数据结构实现双端栈,即一个存储空间存放两个不同的栈
1.利用数组实现双端栈(两个栈相向生长)
2.利用双端队列deque实现双端栈(两个栈反向生长)
================================================
利用数组实现双端栈(两个栈相向生长)
1. 源代码:
//----------------------------------------------------------------------------
Stack.h
//----------------------------------------------------------------------------
#include <iostream>
using namespace std;
typedef int stackElement;
class stack
{
public:
stack(int s);
bool empty(int x) const;
bool full() const;
void push(int x,const stackElement & value);
void pop(int x);
stackElement top(int x) const;
private:
stackElement *array;
int fTop;
int bTop;
int size;
};
stack::stack(int s)
{
size=s;
array=new int[size];
fTop=-1;
bTop=size;
}
bool stack::empty(int x) const
{
switch (x)
{
case 1:
if(fTop==-1){
return true;
}else{
return false;
}
break;
case 2:
if(bTop==size){
return true;
}else{
return false;
}
break;
}
}
bool stack::full() const
{
if(fTop >= bTop-1){
return true;
}else{
return false;
}
}
void stack::push(int x,const stackElement & value)
{
if(x==1){
if(!full()){
++fTop;
array[fTop]=value;
}else{
cerr<<" *** stack full -- can't add new value ***\n"
" Must increase value of size in stack.h\n";
exit(1);
}
}else if(x==2){
if(!full()){
--bTop;
array[bTop]=value;
}else{
cerr<<" *** stack full -- can't add new value ***\n"
" Must increase value of size in stack.h\n";
exit(1);
}
}
}
void stack::pop(int x)
{
if(x==1){
if(!empty(x)){
fTop--;
}else{
cerr<< "*** stack is empty -- can't remove a value ***\n";
}
}else if(x==2){
if(!empty(x)){
bTop++;
}else{
cerr<< "*** stack is empty -- can't remove a value ***\n";
}
}
}
stackElement stack::top(int x) const
{
if(x==1){
if (!empty(x)){
return array[fTop];
}else{
cerr<< "*** stack is empty -- returning garbage value ***\n";
stackElement garbage;
return garbage;
}
}else if(x==2){
if (!empty(x)){
return array[bTop];
}else{
cerr<< "*** stack is empty -- returning garbage value ***\n";
stackElement garbage;
return garbage;
}
}
}
//----------------------------------------------------------------------------
Stack.cpp
//----------------------------------------------------------------------------
#include <iostream>
using namespace std;
#include "stack.h"
int main()
{
int a;
cout<<"input the stack capacity: ";
cin>>a;
stack s(a);
int i,j,n,m;
int x=0;
int y=1;
cout<<"Stack created. Empty? "<<endl<<boolalpha<<"stack1: "<<s.empty(1)<<" stack2: "<<s.empty(2)<<endl;
cout<<"How many elements to add to the frontstack? ";
cin>>n;
for(i=1;i<=n;i++){
s.push(1,x);
x+=2;
}
cout<<"How many elements to add to the backstack? ";
cin>>m;
for(j=1;j<=m;j++){
s.push(2,y);
y+=2;
}
cout<<endl;
cout<<"Stack empty? "<<"stack1: "<<s.empty(1)<<" stack2: "<<s.empty(2)<<endl;
cout<<"Stack full? "<<s.full()<<endl;
cout<<"frontTop value? "<<s.top(1)<<endl;
cout<<"backTop value? "<<s.top(2)<<endl;
while (!s.empty(1)){
cout<<"front popping "<<s.top(1)<<endl;
s.pop(1);
}
while (!s.empty(2)){
cout<<"back popping "<<s.top(2)<<endl;
s.pop(2);
}
cout<<"Stack empty? "<<"stack1: "<<s.empty(1)<<" stack2: "<<s.empty(2)<<endl;
return 0;
}
代码分析:
在stack.h头文件中设置一个类stack,实现这些操作的函数成员:构造函数stack(),empty()检查一个栈并根据栈中是否包含值来返回false或true,full()检查一个栈是否栈满并根据栈中是否包含值来返回false或true,push()通过在栈的顶部添加一个值来修改栈,top()提取栈顶的值,pop()通过从栈顶删除一个值来修改栈,和3个整型变量fTop、bTop、size。
栈1插入偶数,栈2插入奇数。
在push(int x,const stackElement & value){}中以x为形参,由1和2来判断是插入栈1还是栈2,以栈1为例,首先判断栈中是否栈满,若不满,将fTop++,让数组相应位子加入传入的值,若满,则报错。
在empty(int x) 中以x为形参,由1和2来判断栈1还是栈2栈空。
在pop(int x){}中以x为形参,由1和2来判断是操作栈1还是栈2,以栈1为例,首先判断栈中是否栈满,若不空,将fTop--,栈顶值出栈,若空,则报错。
在top(int x){}中以x为形参,由1和2来判断是输出栈1还是栈2的栈顶值,以栈1为例,首先判.断栈中是否栈满,若不空,返回栈顶值,即return array[fTop];,若空,报错。
在主函数中一开始先判断栈是否为空,为空继续输入放入栈1几个值,放入栈2几个值,随机生成这些值,再次判空,为非空,判满,为非满,输出此时2个栈中栈顶值,然后遍历输出2栈中值,一边输出top(),一边pop(),遍历完成,判空表示为空,结束程序。
利用双端队列deque实现双端栈(两个栈反向生长)\
1. 源代码:
//----------------------------------------------------------------------------
deque.h
//----------------------------------------------------------------------------
#include<deque>
#include<iostream>
using namespace std;
class deQueue
{
public:
deQueue();
int size() const;
bool empty() const;
void push(int x,const int& item);
void pop(int x);
int top(int x) const;
private:
deque<int> dequeue;
int fTop;
int bTop;
};
deQueue::deQueue()
{
fTop=0;
bTop=0;
}
bool deQueue::empty() const
{
if((fTop==0) && (bTop==0)){
return true;
}else{
return false;
}
}
void deQueue::push(int x,const int& item)
{
switch (x)
{
case 1:
++fTop;
dequeue.push_front(item);
break;
case 2:
++fTop;
dequeue.push_back(item);
break;
}
}
void deQueue::pop(int x)
{
if(dequeue.size()==0){
cerr<< "*** stack is empty -- can't remove a value ***\n";
exit(1);
}
switch (x)
{
case 1:
--fTop;
dequeue.pop_front();
break;
case 2:
--bTop;
dequeue.pop_back();
break;
}
}
int deQueue::top(int x) const
{
if(dequeue.size()==0){
cerr<< "*** stack is empty -- can't remove a value ***\n";
exit(1);
}
switch (x)
{
case 1:
return dequeue.front();
break;
case 2:
return dequeue.back();
break;
}
}
int deQueue::size() const
{
return dequeue.size();
}
//----------------------------------------------------------------------------
deque.cpp
//----------------------------------------------------------------------------
#include "deque.h"
int main(int argc, char* argv[])
{
deQueue s;
int i,j,n,m;
int x=0;
int y=1;
cout<<"Stack created. Empty? "<<boolalpha<<s.empty() <<endl;
cout<<"How many elements to add to the frontstack? ";
cin>>n;
for(i=1;i<=n;i++){
s.push(1,x);
x+=2;
}
cout<<"How many elements to add to the backstack? ";
cin>>m;
for(j=1;j<=m;j++){
s.push(2,y);
y+=2;
}
cout<<endl;
cout<<"Stack empty? "<<s.empty()<<endl;
cout<<"frontTop value? "<<s.top(1)<<endl;
cout<<"backTop value? "<<s.top(2)<<endl;
while (!s.empty()){
cout<<"front popping "<<s.top(1)<<endl;
s.pop(1);
cout<<"back popping "<<s.top(2)<<endl;
s.pop(2);
}
cout<<"Stack empty? "<<s.empty()<<endl;
return 0;
}
代码分析:
再deque.h中设置一个类deQueue,实现这些操作的函数成员:构造函数dequeue (),empty()检查一个栈并根据栈中是否包含值来返回false或true,push()通过在栈的顶部添加一个值来修改栈,top()提取栈顶的值,pop()通过从栈顶删除一个值来修改栈。在private中定义一个双端队列dequeue,和2个整型变量fTop、bTop。
栈1插入偶数,栈2插入奇数。
在push(int x,const int& item){}中以x为形参,由1和2来判断是插入栈1还是栈2,以栈1为例,因为双端队列是反向生长,可以无限扩容,所以不必像数组判断是否栈满fTop++,使用deque的dequeue.push_front(item);功能,push一个值。
在pop(int x){}中以x为形参,首先判断栈是否为空if(dequeue.size()==0),若栈为空,报错退出,若栈不为空,由1和2作为参数传递来判断是操作栈1还是栈2,以栈1为例,fTop--,栈顶值出栈。
在top(int x){}中以x为形参,首先判断栈是否为空if(dequeue.size()==0),若栈为空,报错退出,若栈不为空,由1和2作为参数传递来判断是操作栈1还是栈2,以栈1为例,返回栈顶值,即return dequeue.front()。
因为在主函数中输出top(),pop()栈顶值中可以遍历该双端队列中的栈1和栈2,所以没有必要再设置display(){}函数。
在主函数中一开始先判断栈是否为空,为空继续输入放入栈1几个值,放入栈2几个值,随机生成这些值,再次判空,为非空,输出此时2个栈中栈顶值,然后遍历输出2栈中值,一边输出top(),一边pop(),遍历完成,判空表示为空,结束程序。