数据结构之栈(C/C++实现)

定义

栈是仅限定在表尾进行插入和删除操作的线性表。
我们把允许插入和删除的一段称为栈顶,另一端称为栈底,不包含任何数据元素的称为空栈。栈又称为后进先出的线性表。简称为LIFO结构。

栈的抽象数据类型

ADT 栈(stack)
Data 
    同线性表。元素具有相同的类型。相邻元素具有前驱和后继关系
Operation
    InitStack(*S)  :初始化操作,建立一个空栈
    DestroyStack(*S): 若栈存在,则销毁它
    ClearStack(*S): 将栈清空
    StackEmpty(S):若栈为空,返回true,否则返回false
    GetTop(S,*e):若栈存在且非空,用e返回S的栈顶元素
    Push(*S,e):若栈S存在,插入新元素e到栈S中并成为栈顶元素。
    Pop(*S,*e):删除栈S中栈顶元素,并用e返回其值。
    StackLength(S):返回栈S的元素个数

栈的顺序存储结构

1.结构定义

用数组来存储:下标为0作为栈底,用变量top来指示栈顶元素在数组中的位置
(C语言)

#define MAXSIZE 50
#define OK 1
#define ERROR 0
#define True 1
#define False 0
typedef int Status;/*函数的返回类型,这里定义为int*/
typedef int SElemType;/*SElemType根据情况来顶,这里假设为int*/
typedef struct
{
    SElemType data[MAXSIZE];
    int top;    /*用于栈顶指针*/
}SqStack;

2.进栈操作

/*插入元素e为新的栈顶元素*/
Status Push(SqStack *S,SElemType e)
{
    if(S->top==MAXSIZE-1)     //栈满
    {
        return ERROR;
    }
    S->top++;   //栈顶指针加1
    S->data[S->top]=e;
    return OK;
}

3.出栈操作

/*若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR*/
Status Pop(SqStack *S,SElemType *e)
{
    if(S->top==-1)
    {
        return ERROR;
    }
    *e=S->data[S->top];
    S->top--;
    return OK;
}

两栈共享空间

为了克服顺序存储时,栈的存储空间必须事先确定这一缺点,我们可以利用共享栈。
共享栈,就是数组有两个端点,两个栈有两个栈底,让一个栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下端为数组长度n-1处。这样,两个栈如果增加元素,就是两端点向中间延伸。
定义top1和top2是栈1和栈2的栈顶指针
栈满的情况:
top1为空栈 ,top2指向0时,栈2满
top2为空栈,top1指向n-1时,栈1满
当top1+1=top2时,栈满

两栈共享空间的结构的代码如下:

/*两栈共享空间结构*/
typedef struct
{
    SElemType data[MAXSIZE];
    int top1;  //栈1栈顶指针
    int top2;  //栈2栈顶指针
}SqDoubleStack;

入栈操作:

Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
    if(S->top1+1==S->top2)  //栈已满,不能再push新元素了
    {
        return ERROR;
    }
    if(stackNumber==1)  //向栈1插入元素
    {
        S->data[++S->top1]=e;
    }
    else if(stackNumber==2)  //向栈2插入元素
    {
        S->data[--S->top2]=e;
    }
    return OK;
}

出栈操作:

Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{
    if(stackNumber==1)
    {
        if(S->top1==-1)  //栈1已空,无法弹出
        {
            return ERROR;
        }
        *e=S->data[S->top1--];
    }
    if(stackNumber==2)
    {
        if(S->top2==MAXSIZE) //栈2已空,无法弹出
        {
            return ERROR;
        }
        *e=S->data[S->top2++];
    }
    return OK;
}

栈的链式存储结构

链栈的结构代码:

typedef struct StackNode
{
    SElemType data;
    struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct LinkStack
{
    LinkStackPtr top;
    int count;
}LinkStack;

进栈代码:

Status Push(LinkStack *S,SElemType e)
{
    LinkStackPtr s=(LinkStackPtr)malloc(sizeof (StackNode));
    s->data=e;
    s->next=S->top;  //把当前的栈顶元素赋值给新节点的直接后继
    S->top=s;    /*将新的节点s赋值给栈顶指针*/
    S->count++;
    return OK;
}

出栈代码:

Status Pop(LinkStack *S,SElemType *e)
{
    LinkStackPtr p;
    if(StackEmpty(*S))
    {
        return ERROR;
    }
    *e=S->top->data;
    p=S->top;       /*将栈顶节点赋值给p*/
    S->top=S->top->next;   /*使栈顶指针后移一位,指向后一节点*/
    free(p);             /*释放节点p*/
    S->count--;
    return OK;
}

栈的应用

  • 递归
  • 四则运算表达式求值

栈的C++实现

#include <iostream>
using namespace std;
template<typename T>
class Stack
{
public:
    Stack(int s=10);
    ~Stack();
    bool StackEmpty();
    int StackLength();
    T GetTop(T &e);
    void Push(T e);
    T Pop(T &e);
private:
    T *base;
    T *top;
    int stacksize,count;
    T *array;
};

template<typename T>
Stack<T>::Stack(int s)
{
    array=new T[s];
    stacksize=s;
    count=0;
    top=base=array;
}

template<typename T>
Stack<T>::~Stack<T>()
{

}

template<typename T>
int Stack<T>::StackLength()
{
    return count;
}

template<typename T>
bool Stack<T>::StackEmpty()
{
    return count==0;
}

template<typename T>
T Stack<T>::GetTop(T &e)
{
    e=*(top-1);
    return e;
}

template<typename T>
void Stack<T>::Push(T e)
{
    if(count+1<=stacksize)
    {
        count++;
        *top=e;
        top++;
    }
    else
    {
        cout<<"栈空间不足"<<endl;
    }
}

template<typename T>
T Stack<T>::Pop(T &e)
{
    if(count==0)
    {
        cout<<"栈已空,无法弹出"<<endl;
    }
    else
    {
        e=*(top-1);
        top--;
        count--;
    }
    return e;
}

int main()
{
    Stack<int> a1(9);
    for(int i=0;i<9;i++)
    {
        a1.Push(i);
    }
    cout<<"栈的大小:"<<a1.StackLength()<<endl;
    cout<<"栈是否为空:"<<a1.StackEmpty()<<endl;
    int e;
    cout<<"栈顶元素:"<<a1.GetTop(e)<<endl;
    while (!a1.StackEmpty())
    {
        int e;
        cout<<a1.Pop(e)<<endl;
    }
    system("pause");
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值