五、栈的定义及运算

定义:

栈(stack)是限定在表的一端进行插入和删除运算的线性表,通常将插入、删除的一端称为栈顶(top),另一端称为栈底。不含元素的空表称为空栈。

特点:

  • 后进先出(Last In First Out)的线性表,简称 LIFO

栈的顺序存储结构和基本运算

栈的顺序存储结构称为顺序栈。类似顺序表的定义,顺序栈也是用数组实现的。因为栈底位置是固定不变的,栈顶位置随着进栈和出栈操作而变化的,因此用一个整形量top来表示栈顶位置,通常称top为栈顶指针。

顺序栈SeqStack定义如下:
#define StackSize 100   //栈大小
typedef char DataType;
typedef struct {
    DataType data[StackSize]; //用数组存放结点
    int top;                  //表示栈顶指针
}SeqStack;
SeqStack S;

S.top<0表示空栈,S.top = StackSize - 1 表示栈满。
当栈满时再做进栈运算必定产生空间溢出,简称上溢,当栈空时再做退栈运算也会产生溢出,简称下溢

顺序栈基本运算
#include "stdio.h"
#include "stdlib.h"

#define StackSize 100   //栈大小
typedef char DataType;
typedef struct {
    DataType data[StackSize]; //用数组存放结点
    int top;                  //表示栈顶指针
}SeqStack;
SeqStack S;

/*
    置空栈
    S.top<0表示空栈
 */
void InitStack(SeqStack *S){
    S->top = -1;
}

/*
    判断栈空
 */
int StackEmpty(SeqStack *S){
    return S->top == -1;
}

/*
    判断栈满
 */
int StackFull(SeqStack *S){
    return S->top == StackSize-1;
}

/*
    进栈(入栈)
 */
void Push(SeqStack *S, DataType x){
    if (StackFull(S)){
        printf("栈满\n");
    }
    else{
        S->top = S->top + 1;    //栈顶指针加1
        S->data[S->top] = x;    //将X入栈
    }
    
}

/*
    退栈(出栈)
 */
DataType Pop(SeqStack *S){
    if (StackEmpty(S))
    {
        printf("空栈\n");
        exit(0);
    }
    else
    {
        return S->data[S->top--];   //返回栈顶元素并且栈顶指针减1
    }
}

/*
    去栈顶元素(不改变栈顶指针)
 */

DataType GetTop(SeqStack *S){
    if (StackEmpty(S))
    {
        printf("栈满\n");
        exit(0);
    }
    else
    {
        return S->data[S->top];
    }
}

栈的链式存储结构及运算

由于顺序存储分配固定的空间会产生的溢出和空间浪费的问题,可以采用链式存储结构来存储栈。
栈的链式存储称为链栈,因为是受限的单链表,插入和删除操作都限制在表头(栈顶)位置,因此不需要设置头结点,将单链表头指针head改为栈顶指针top即可。

链式栈LinkStack结构如下:
typedef int DataType;
typedef struct stacknode
{
    DataType data;
    struct stacknode * next;
}StackNode;
typedef StackNode * LinkStack;
LinkStack top;

链栈的基本运算
/*
    判断栈空
 */
int StackEmpty(LinkStack top){
    return top == NULL;
}

/*
    进栈
    将新元素插入栈顶
 */
LinkStack Push(LinkStack top,DataType x){
    StackNode * p;
    p = (StackNode *)malloc(sizeof(StackNode));  //申请新结点
    p->data = x;    //新结点赋值
    p->next = top;  //将新结点插入到栈顶
    top = p;        //是top指向栈顶
    return top;     //返回栈顶新指针
}

/*
    退栈(出栈)
 */
LinkStack Pop(LinkStack top,DataType *x){
    StackNode * p = top;    //保存栈顶指针
    if (StackEmpty(top))
    {
        printf("栈为空\n");
        exit(0);
    }
    else
    {
        *x = p->data;       //保存删除结点的值
        top = p->next;      //栈顶指向下一个结点
        free(p);            //释放删除结点
        return top;         //返回新结点
    }
}

DataType GetTop(LinkStack top){
    if (StackEmpty(top))
    {
        printf("栈为空\n");
        exit(0);
    }
    else
    {
        return top->data;
    }
    
}

你可能感兴趣的:(数据结构)