数据结构——栈总结

用顺序和链式实现了线性表,这次要从顺序和链式实现栈了。
栈:限定仅在表尾进行插入和删除操作的线性表。
允许插入和删除的一端称为栈顶,另一端称为栈底
操作特性:后进先出
注意:栈只是对表插入和删除操作的位置进行了限制,并没有限定插入和删除操作进行的时间。

栈的顺序存储结构及实现

顺序栈——栈的顺序存储结构

进栈:top加1
出栈:top减1
栈空空:top= -1
栈满:top= MAX_SIZE-1

//顺序栈类的声明:
const  int  MAX_SIZE=100;
template <class T>
class  seqStack
{
    public:
        seqStack();
        ~seqStack();
        void  Push(T x);
        T Pop();
        T GetTop();
        bool Empty();
    private:
        T data[MAX_SIZE];
        int top;
}
//入栈
template <class T>
void  seqStack<T>::Push(T  x)
{
     if (top==MAX_SIZE-1)  throw  “溢出”;
     top++;
     data[top]=x;
 } 
//判断是否是空栈
template <class T>
bool  seqStack<T>::Empty()
{
     if (top==-1)  
         return true;
     return false;
 } 
//取栈顶
template <class T>
T  seqStack<T>::GetTop()
{
     if (Empty()) throw  ”空栈” ;
     return data[top];
 } 
//—出栈
template  <class  T>
T  seqStack<T>:: Pop()
{
     if (top==-1)  throw  “溢出”; 
     x=data[top];
      top--;
     return  x;
}

在一个程序中需要同时使用具有相同数据类型的两个栈,如何顺序存储这两个栈?
解决方案1:
直接解决:为每个栈开辟一个数组空间。
两栈共享空间:使用一个数组来存储两个栈,让一个栈的栈底为该数组的始端,另一个栈的栈底为该数组的末端,两个栈从各自的端点向中间延伸。
解决方案2
顺序栈单向延伸——使用一个数组来存储两个栈。
栈1的底固定在下标为0的一端;
栈2的底固定在下标为StackSize-1的一端。
top1和top2分别为栈1和栈2的栈顶指针;
Stack_Size为整个数组空间的大小。
在这里插入图片描述
栈1为空top1== -1
栈2为空top2== Stack_Size
栈满top2=top1+1
在这里插入图片描述

//两栈共享空间类的声明:
const int Stack_Size=100;  
template <class T>
class BothStack 
{
  public:
       BothStack();
       ~BothStack(); 
       void Push(int i, T x);   
       T Pop(int i);          
       T GetTop(int i);       
       bool Empty(int i);     
  private:
       T data[Stack_Size];     
       int top1, top2;        
};
//两栈共享空间的实现——插入
template <class T> 
void BothStack<T>::Push(int i, T x )
{
    if (top1==top2-1) //如果栈满,则抛出上溢异常;
		throw "上溢";
/*若在栈1插入,则
top1加1;
在top1处填入x;*/
    if (i==1)
		data[++top1]=x;
/*若在栈2插入,则
top2减1;
在top2处填入x;*/
	if (i==2)
		data[--top2]=x;
}
//两栈共享空间的实现——删除 
template <class T>
T BothStack<T>::Pop(int i){
/*若是在栈1删除,则
若栈1为空栈,抛出下溢异常;
删除并返回栈1的栈顶元素;*/
	if (i==1)
	{   
        if (top1== -1) 	throw "下溢";
        return data[top1--];
    }
/*若是在栈2删除,则
若栈2为空栈,抛出下溢异常;
删除并返回栈2的栈顶元素;*/
	if (i==2) 
	{
		if (top2==StackSize)  	throw "下溢";
    	return data[top2++]; 
 	}
}
//判断某个栈空算法
template <class T> 
bool BothStack<T>::Empty(int i)
{  
    if(i==1){
        if(top1==-1) return 1;
        else return 0;
    }
    if(i==2)	{
        if(top2==StackSize)	return 1;
        else  return 0;
    }
}
//取某个栈栈顶的算法
template <class T> 
T BothStack<T>::GetTop(int i)
{
    if(i==1){
        if(top1!=-1) return data[top1];
    }
    if(i==2){
        if(top2!=StackSize)  return data[top2];
   } 
}
链栈——栈的链接存储结构
//链栈的类声明:
struct Node
{
    int data;
    Node *next;
};
template <class T>
class LinkStack
{    
   public:
         LinkStack() {top=NULL;};
         ~LinkStack();            
         void Push(T x); 
         T Pop(); 
         T GetTop();
         bool Empty();
   private:
         Node<T> *top; 
}
//插入:
template <class T>
void LinkStack<T>::Push(T x)
{
    s=new Node<T>;
    s->data=x; 
    s->next=top; 
   top=s; 
}
//删除:
template <class T>
T LinkStack<T>::Pop()
{
    if (top==NULL)
     throw "下溢";
    x=top->data; 
    p=top; 
    top=top->next;   //不能用top++,链式存储地址不连续
    delete p;
    return x;
}
//析构
template <class T>
LinkStack<T>::~LinkStack()
{
	while (top)
	{
		Node<T> *p;
		p=top->next;
        		delete top;
		top=p;
	}
}

顺序栈和链栈的比较:
时间性能相同
空间性能:
顺序栈:有元素个数的限制和空间浪费的问题。
链栈:没有栈满的问题,只有当内存没有可用空间时才会出现栈满,但是每个元素都需要一个指针域,从而产生了结构性开销。
结论:当栈的使用过程中元素个数变化较大时,用链栈是适宜的,反之,应该采用顺序栈。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值