栈:限定仅在表尾进行插入和删除操作的线性表。

允许插入和删除的一端称为栈顶,另一端称为栈底。

栈的操作特性:后进先出

ex:有三个元素按a、b、c的次序依次进栈,且每个元素只允许进一次栈,则可能的出栈序列有多少种?

1.a入栈,a出栈,b入栈,b出栈,c入栈c出栈——序列abc

2.a入栈,b入栈,b出栈,a出栈,c入栈c出栈——序列bac
3.a入栈,a出栈,b入栈,c入栈,c出栈b出栈——序acb
4.a入栈,b入栈,c入栈,c出栈,b出栈a出栈——序列cab

注意:栈只是对表插入和删除操作的位置进行了限制,并没有限定插入和删除操作进行的时间。

一、栈的顺序存储结构:

1.确定用数组的哪一端表示栈底。

2.附设指针top指示栈顶元素在数组中的位置:

进栈:top加1

出栈:top减1

栈空:top=  -1

栈满:top=  MAX_SIZE-1

顺序栈类的声明:

const
int MAX_SIZE=100;

template

class
seqStack

{

public:

seqStack ( ) ;

~seqStack ( );

void Push ( T x );

T Pop ( );

T GetTop ( );

bool Empty ( );

private:

T data[MAX_SIZE];

int top;

}

顺序栈的实现——入栈

template

void seqStack::Push ( T x)

{

 if (top==MAX_SIZE-1)  throw 

“溢出”;

 top++;

 data[top]=x;

}

  1. 顺序栈的实现—判断是否是空栈

    template

    bool
    seqStack::Empty ()

    {

      if
    

(top==-1)

       return

true;

          return

false;

} 

3.取栈顶

template

T seqStack::GetTop ( )

{

 if (Empty()) throw  ”空栈” ;

 return data[top];

}

  1. 出栈

template

T seqStack:: Pop ( )

{

 if (top==-1)  throw 

“溢出”;

 x=data[top];

  top--;

 return 

x;

}

5.出栈

template

T seqStack:: Pop ( )

{

 if (top==-1)  throw 

“溢出”;

 x=data[top];

  top--;

 return 

x;

}

两栈共享空间:使用一个数组来存储两个栈,让一个栈的栈底为该数组的始端,另一个栈的栈底为该数组的末端,两个栈从各自的端点向中间延伸。

栈1的底固定在下标为0的一端;

栈2的底固定在下标为StackSize-1的一端。

top1和top2分别为栈1和栈2的栈顶指针;

Stack_Size为整个数组空间的大小;

top1== -1时栈1为空,top2== Stack_Size时栈2为空

两栈共享空间类的声明

const int
Stack_Size=100;

template

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;        

};

  1. 两栈共享空间的实现——插入

  2. 如果栈满,则抛出上溢异常;

  3. 判断是插在栈1还是栈2;

    2.1 若在栈1插入,则
    
          2.1.1 top1加1;
    
          2.1.2 在top1处填入x;
    
    2.2 若在栈2插入,则
    
          2.2.1 top2减1;
    
          2.2.2 在top2处填入x;
    

代码:

template

void
BothStack::Push(int i, T x )

{

if (top1==top2-1) 

   throw "上溢";

if (i==1) 

   data[++top1]=x;

if (i==2) 

   data[--top2]=x;

}

两栈共享空间的实现——删除

1.若是在栈1删除,则

1.1 若栈1为空栈,抛出下溢异常;

1.2 删除并返回栈1的栈顶元素;

2.若是在栈2删除,则

2.1 若栈2为空栈,抛出下溢异常;

2.2 删除并返回栈2的栈顶元素;

template

T
BothStack::Pop(int i){

if (i==1) {   

    if (top1== -1)   throw "下溢";

    return data[top1--];

}

if (i==2) {                           

    if (top2==StackSize)    throw

“下溢”;

    return data[top2++]; 

}

}

栈空

template

bool BothStack::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

T BothStack::GetTop(int i)

{

if(i==1) {

if (top1!=-1) return data[top1];

}

if(i==2) {

if(top2!=StackSize) return
data[top2];

}

}

二.栈的链式存储

链栈的类声明

template

class LinkStack

{

public:

     LinkStack( ) {top=NULL;};

     ~LinkStack( );            

     void Push(T x); 

     T Pop( ); 

     T GetTop( );

     bool Empty( );

private:

     Node<T> *top; 

}

  1. 链栈的实现——插入(入栈)

template

void LinkStack::Push(T x)

{

s=new Node<T>;

s->data=x; 

s->next=top; 

top=s;

}

  1. 链栈的实现——删除(出栈)

template

T LinkStack::Pop( )

{

if (top==NULL)

 throw "下溢";

x=top->data; 

p=top; 

top=top->next;   

delete p;

return x;

}

  1. 链栈的实现——链栈的析构(链栈的销毁)

template

LinkStack::~LinkStack( )

{

while (top)

{

   Node<T> *p;

   p=top->next;

          delete top;

   top=p;

}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]提供了一个朴素的解法,使用两个来存储字符串,一个用来存储普通字符,另一个用来存储特殊字符。遍历字符串,如果是普通字符则压入第一个,如果是特殊字符则弹出第一个顶元素。最后比较两个是否相同即可判断字符串是否有效。这个解法的时间复杂度是O(M + N),空间复杂度也是O(M + N)。\[1\] 引用\[2\]提供了另一个的应用场景,即判断括号是否有效。遍历字符串,如果是左括号则压入,如果是右括号则判断和顶元素是否匹配,不匹配则返回false,匹配则弹出栈顶元素。最后判断是否为空即可判断括号是否有效。\[2\] 引用\[3\]也提供了一个判断括号是否有效的解法,使用来操作。遍历字符串,如果是左括号则压入,如果是右括号则判断和顶元素是否匹配,不匹配则返回false,匹配则弹出栈顶元素。最后判断是否为空即可判断括号是否有效。这个解法使用了HashMap来存储括号的对应关系。\[3\] 综上所述,在解决字符串相关问题中有着广泛的应用,包括判断字符串是否有效、逆波兰表达式等。在解决这些问题时,可以帮助我们保存和处理字符的顺序,从而简化问题的处理过程。 #### 引用[.reference_title] - *1* *3* [Leetcode刷题03-](https://blog.csdn.net/weixin_47802917/article/details/123007699)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v4^insert_chatgpt"}} ] [.reference_item] - *2* [leetCode-类型详解](https://blog.csdn.net/zhiyikeji/article/details/125508011)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v4^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值