3.1 数据结构——栈

本文详细介绍了栈的定义、抽象数据类型、顺序存储结构及其操作实现,包括栈的初始化、判断空栈、获取栈长度、清空栈、销毁栈、入栈和出栈。此外,还提到了栈的链式存储结构及其操作,如链栈的初始化、入栈和出栈。内容涵盖了栈的基本概念和常用操作,适合计算机科学初学者理解。
摘要由CSDN通过智能技术生成

3.1.1 栈的定义

        栈(stack)是限定仅在表尾进行插入和删除操作的线性表;又称为后进先出(Last In First Out)的线性表,简称LIFO结构。

        栈的表尾(即an端)称为栈顶(TOP),表头(即a1端)成为栈底;栈的插入操作称为进栈,也称为压栈、入栈,栈的删除操作称为出栈。

栈的结构示意图:

3.1.2 栈的抽象数据类型

 ADT Stack{

    数据对象:
        D = {ai | ai ∈ Elemset, i = 1, 2, ..., n, n >= 0}

    数据关系:
        R1 = {<ai-1, ai> | ai-1, ai ∈ D, i = 2, ..., n}
        约定an端为栈顶,a1端为栈底。

    基本操作:
        InitStack(*S)  //初始化栈
        操作结果:构建一个空栈S。

        DestoryStack(*S) //销毁栈
        初始条件:栈S已存在。
        操作结果:栈S被销毁。

        StackEmpty(S) //判断S是否为空栈
        操作结果:若栈S为空栈,返回TRUE,否则返回FALSE。

        StackLength(S) //求栈的长度
        初始条件:栈S已存在。
        操作结果:返回栈S的元素个数。

        GetTop(S, *e)  //取栈顶元素
        初始条件:栈S已存在且非空。
        操作结果:用e返回S的栈顶元素。

        ClearStack(*S)  //清空栈S
        初始条件:栈S已存在。
        操作结果:将栈S清空。

        PushStack(*S, e) //入栈操作
        初始条件:栈S已存在。
        操作结果:插入元素e为新的栈顶元素。

        PopStack(*S, *e) //出栈操作
        初始条件:栈S已存在。
        操作结果:删除S的栈顶元素an,并用e返回它的值。
}

3.1.3 栈的顺序表示

存储方式:利用一组地址连续的存储单元一次存放自栈底到栈顶的数据元素,栈底一般在低地址端。

 1、附设top指针,指示栈顶元素在顺序栈中的位置。

 2、另设base指针,指示栈底元素在顺序栈中的位置。

3、为了方便操作,通常top指针知识真正栈顶元素之上的下标地址。

4、另外使用stacksize表示栈可使用的最大容量。

 空栈:base == top是栈空标志

栈满:top - base == stacksize

使用数组作为顺序栈存储方式的特点:简单、方便、但产生溢出(数组大小固定)。

上溢(overflow):栈已经满,又要压入元素。

下溢(underflow):栈已经空,还要弹出元素。

 3.1.4 顺序栈的实现

1、方式一:

(1)栈的数据类型定义:

#define MAXSIZE 100

#define TRUE 0
#define FALSE -1


typedef int Status;

typedef int ElemType;

typdef struct
{
    ElemType *base;  //栈顶指针
    ElemType *top;   //栈底指针
    int stacksize;   //栈的最大容量
}SqStack;

(2)判断栈是否为空

//判断栈是否为空,只需判断top指针和base指针的指向是否相等
Status StackEmpty(SqStack S)
{
    if (S.top == S.base)
        return TRUE;
    else
        return FALSE;
}

(3)求栈的长度

int StackLength(SqStack S)
{
    //两个指针相减求长度只适用于两个指针都指向同一个数组
    return S.top - S.base;
}

(4)清空栈

Status ClearStack(SqStack *S)
{
    if (S.base)  //判断栈是否存在
        S.top = S.base;
    return TRUE;
}

(5)销毁栈

Status DestoryStack(SqStack *S)
{
    ElemType *p;
    if (S->base)
    {
        for (int i = 0; i < S->stacksize; i++)
        {
            p = S->base;
            S->base++;
            free(p);
            p = NULL;
        }
        S->stacksize = 0;
        S->base = S->top = NULL;
    }
    return TRUE;
}

(6)入栈操作

Status PushStack(SqStack *S, ElemType e)
{
    if (S->top - S->base == S->stacksize) //判断栈是否已满
        return FALSE;

    *(S->top) = e;
    S->top++;
    return TRUE;
}

(7)出栈操作

Status PopStack(SqStack *S, ElemType *e)
{
    if (S->base == S->top) //判断栈是否为空
        return FALSE;
    
    S->top--;
    e = S->top;
    return TRUE;
}

2、方式二

(1)栈的数据类型定义

#define MAXSIZE 100
#define TRUE 0
#define FLASE -1

typedef int ElemType;
typedef int Status;

typedef struct
{
    ElemType data[MAXSIZE];
    int top;       //用于保存栈顶元素的下标
}SqStack;

(2)判断栈是否为空

Status StackEmpty(SqStack S)
{
    if (S.top == 0)
        return TRUE;
    else
        return FALSE;
}

(3)求栈的长度

int StackLength(SqStack)
{
    return S.top;
}

(4)清空栈

Status ClearStack(SqStack *S)
{
    S.top = 0;
    return TRUE;
}

(5)入栈操作

Status PushStack(SqStack *S, ElemType e)
{
    if (S->top == MAXSIZE)
        return FALSE;

    S->data[S->top] = e;
    S->top++;
    return TRUE;
}

(6)出栈操作

Status PopStack(SqStack *S, ElemType *e)
{
    if (S->top == 0)
        return FALSE;

    S->top--;
    *e = S->data[S->top];
    return TRUE;
}

3.1.5 栈的链式存储结构

3.1.5.1 链栈的表示

        链栈是运算受限的单链表,只能在链表头部进行操作。

 (1)链栈的头指针就是栈顶

(2)不需要头结点

(3)基本不存在栈满的情况

(4)空栈相当于头指针指向空

(5)插入和删除均在栈顶操作

3.1.5.2 链栈的实现

1、链栈的类型定义

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

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

2、链栈的初始化

Status InitLinkStack(LinkStack *S)
{
    S->LinkStackPtr = NULL;
    S->count = 0;
    return TRUE;
}

3、取栈的长度

int LinkStackLength(LinkStack S)
{
    return S.count;
}

4、链栈的入栈操作

Status PusLinkStack(LinkStack *S, ElemType e)
{
    LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
    p->data = e;
    p->next = S->top;
    S->top = p;
    S->count++;
    return TRUE;
}

5、链栈的出栈操作

Status PopLinkStack(LinkStack *S, ElemType *e)
{
    if (S->count == 0)
        return FALSE;

    LinkStackPtr p;
    *e = S->top->data;
    p = S->top;
    S->top = S->top->next;
    S->count--;
    free(p);
    p = NULL;
    return TRUE;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值