数据结构-栈

栈是线性表,是一种只能在一端进行插入删除的线性表
术语:空栈,栈顶,栈底
示意图
示意图
如上图,进栈顺序为1,2,3,4,5
如果要进行出栈,该栈的出栈顺序只能为,4,3,2,1.
栈的特性后进先出,只能从栈顶方向进行插入和删除操作。
在图中,进栈只能从进栈方向插入,出栈只能将栈顶元素删除。
元素进栈出栈只能在栈顶进行操作
同时,栈可以使用两种存储结构实现,顺序栈和链式栈。

常见操作

Initstack(&s):初始化一个空栈S。
StackEmpty(S):判断一个栈是否为空,若栈s为空则返回 true,否则返回 false。
Push(&s,x):进栈,若栈s未满,则将x加入使之成为新栈顶。
Pop(&S,&x):出栈,若栈S非空,则弹出顶元素,并用x返回。
GetTop(S,&x):读栈顶元素,但不出,若栈s非空,则用x返回顶元素。
DestroyStack(&S):销毁栈,并释放栈s占用的存储空间(“&”表示引用调用)。

顺序栈

定义

typedef struct
{
    int data[MaxSize];
    int top;//指针,指向位置
} SqStack;

采用顺序存储的方式的栈称为顺序栈,利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附加一个指针(top)指向当前元素的位置。

相关操作

初始化

void InitStack(SqStack &S)
{
    S.top = -1;
}

初始化只需要让指针指向-1即可

判空操作

bool StackEmpty(SqStack S)
{
    if (S.top == -1)
        return true;
    else
        return false;
}

判断指针

插入操作(入栈)

bool Push(SqStack &S, int x)
{
    if (S.top == MaxSize - 1)
        return false;
    S.top = S.top + 1;
    S.data[S.top] = x;
    return true;
}

首先判断栈是否还有位置,如果有,则在栈顶下一个位置存放元素。

删除操作(出栈)

bool Pop(SqStack &S, int &x)
{
    if (S.top == -1)
        return false;
    x = S.data[S.top];
    S.top = S.top - 1;
    return true;
}

首先判断栈内是否为空,如不为空,则可进行出栈,这里将出栈元素赋给x,然后指针后移一位

获取栈顶元素
和出栈相似,但不修改指针,只获得x即可

共享栈

在这里插入图片描述

利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸

两个栈的栈顶指针都指向栈顶元素,top0=-1时0号栈为空,top1=Maxsize时1号栈为空;仅当两个栈顶指针相邻**(top1-top0=1)**时,判断为满。当0号栈进栈时top0先加1再赋值,1号栈进栈时 top1 先减1再赋值;出栈时则刚好相反。
共享栈是为了更有效地利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才发生上溢。其存取数据的时间复杂度均为 0(1),所以对存取效率没有什么影响。

链栈

使用链式存储结构,通常使用单链表实现。
优点是便于多个栈共享存储空间和提高效率,且不存在栈满上溢的情况。
通常使用单链表实现,并规定所有在表头实现(栈顶),这里规定链栈没有头节点,Lhead指向栈顶元素。
在这里插入图片描述

相关操作

定义

typedef struct Linknode
{
    int data;
    struct Linknode *next;
} *LiStack;

初始化


// 初始化栈
bool InitStack(LiStack &S)
{
    S = (Linknode *)malloc(sizeof(Linknode));

    if (S == NULL)
        return false;
    S->next = NULL;
    return true;
}

入栈

// 压栈
bool Push(LiStack &S, int e)
{
    Linknode *newNode = (Linknode *)malloc(sizeof(Linknode));
    if (newNode == NULL)
    {
        return false; // 内存分配失败
    }
    newNode->data = e;
    newNode->next = S;
    S = newNode; // 栈顶指针指向新节点
    return true;
}

出栈


// 弹栈
bool Pop(LiStack &S, int &e)
{
    if (S == NULL)
    {
        return false; // 栈空
    }
    Linknode *p = S;
    e = p->data;
    S = S->next; // 栈顶指针指向下一个节点
    free(p);     // 释放弹出的节点
    return true;
}

获取栈顶元素


// 获取栈顶元素
bool GetTop(LiStack S, int &e)
{
    if (S == NULL)
    {
        return false; // 栈空
    }
    e = S->data;
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值