数据结构之堆栈

本文详细介绍了堆栈的概念,包括其线性表特性、操作原则(后入先出LIFO)以及堆栈的抽象数据类型描述。接着展示了堆栈的两种存储实现方式:顺序存储和链式存储,并提供了C语言实现的代码示例。最后,通过有效括号问题阐述了堆栈在解决实际问题中的应用,展示了如何使用堆栈检查括号字符串的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是堆栈

堆栈(Stack): 具有一定操作约束的线性表

  • 只在一端(栈顶)进行插入、删除操作
  • 插入数据:入栈(Push)
  • 删除数据:出栈)(Pop)
  • 后入先出:Last In First Out(LIFO)

堆栈的抽象数据类型描述

类型名称:堆栈Stack
数据对象集:一个有0个或多个元素的有穷线性表
操作集:长度未MaxSize的堆栈S,堆栈元素item(ElementType)
基本操作主要有:

  1. Stack CreateStack(int MaxSize): 生成空堆栈,其最大长度为Maxsize
  2. int IsFull(Stack S, int MaxSize): 判断堆栈S是否已满
  3. void Push(Stack S, ElementType item): 将元素item压入堆栈
  4. int IsEmpty(Stack S): 判断堆栈S是否为空
  5. ElementType Pop(Stack S): 删除并返回栈顶元素

栈的顺序存储实现

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100

typedef struct SNode *Stack;
typedef int ElementType;
struct SNode{
     ElementType Data[MAXSIZE];
     int Top;
};

Stack CreateStack();
int IsFull(Stack s);
void Push(Stack s, ElementType item);
int IsEmpty(Stack s);
ElementType Pop(Stack s);

Stack CreateStack()
{
     Stack stack = (Stack )malloc(sizeof(struct SNode));
     stack->Top = -1;
     return stack;
}
int IsFull(Stack s)
{
     if(s->Top == MAXSIZE-1)
          return 1;
     else
          return 0;
}
void Push(Stack s, ElementType item)
{
     if(IsFull(s))
     {
          printf("the stack is full");
          return ;
     }
     s->Data[++s->Top] = item;
}
int IsEmpty(Stack s)
{
     if(s->Top == -1)
          return 1;
     else
          return 0;
}
ElementType Pop(Stack s)
{
     if(IsEmpty(s))
     {
          printf("the stack is Empty");
          return 0;
     }
     return s->Data[s->Top--];
}

int main()
{
     Stack s = CreateStack();  // 创建一个空栈
     printf("当前栈是否为空,1为空,0为非空:%d\n", IsEmpty(s));  //判断当前栈是否为空
     printf("当前栈是否满,1为满,0为非满:%d\n", IsFull(s));  // 判断当前栈是否满
     printf("1入栈\n");
     Push(s, 1);  //1入栈
     printf("2入栈\n");
     Push(s, 2);  //2入栈
     printf("3入栈\n");
     Push(s, 3);  //3入栈
     int item = Pop(s);  //出栈
     printf("输出出栈元素:%d\n", item);  //输出出栈元素
     printf("当前栈是否为空,1为空,0为非空:%d\n", IsEmpty(s)); //判断当前栈是否为空
     printf("2继续出栈\n");
     Pop(s);
     printf("1继续出栈\n");
     Pop(s);
     printf("当前栈是否为空,1为空,0为非空:%d\n", IsEmpty(s));  //判断当前栈是否为空
}

结果如下:
在这里插入图片描述

栈的链式存储实现

#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
typedef struct SNode *Stack;

struct SNode{
     ElementType Data;
     struct SNode *Next;
};
Stack CreateStack();
int IsEmpty(Stack s);
void Push(ElementType item, Stack s);
ElementType Pop(Stack s);

Stack CreateStack()
{
     Stack s = (Stack )malloc(sizeof(struct SNode));
     s->Next = NULL;
     return s;
}

int IsEmpty(Stack s)
{
     if(s->Next == NULL)
          return 1;
     else
          return 0;
}

void Push(ElementType item, Stack s)
{
     Stack temp = (Stack )malloc(sizeof(struct SNode));
     temp->Data = item;
     temp->Next = s->Next;
     s->Next = temp;
}
ElementType Pop(Stack s)
{
     if(IsEmpty(s))
     {
          printf("the stack is Empty\n");
          return 0;
     }
     Stack temp = s->Next;
     ElementType data = s->Next->Data;
     s->Next = s->Next->Next;
     free(temp);
     return data;
}

int main()
{
     Stack s = CreateStack();
     printf("当前栈是否为空,1为空,0为非空:%d\n", IsEmpty(s));  //判断当前栈是否为空
     printf("1入栈\n");
     Push(1, s);
     printf("2入栈\n");
     Push(2, s);  //2入栈
     printf("3入栈\n");
     Push(3, s);  //2入栈
     int item = Pop(s);
     printf("输出出栈元素:%d\n", item);  //输出出栈元素
     printf("当前栈是否为空,1为空,0为非空:%d\n", IsEmpty(s)); //判断当前栈是否为空
     printf("2继续出栈\n");
     Pop(s);
     printf("1继续出栈\n");
     Pop(s);
     printf("当前栈是否为空,1为空,0为非空:%d\n", IsEmpty(s));  //判断当前栈是否为空

}

在这里插入图片描述

应用:有效的括号020 -力扣

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:

输入: “()”
输出: true
示例 2:

输入: “()[]{}”
输出: true
示例 3:

输入: “(]”
输出: false
示例 4:

输入: “([)]”
输出: false
示例 5:

输入: “{[]}”
输出: true

利用顺序栈去解决该题:
对于读取到’(’,’{’,’{'进行入栈操作
若读取到右括号,则与栈顶元素匹配,若匹配则出栈,否则无效
最后判断栈是否为空,为空则有效,否则无效

代码如下:

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 10002
#include<stdbool.h>
typedef struct SNode *Stack;
typedef char ElementType;
struct SNode{
     ElementType Data[MAXSIZE];
     int Top;
};

Stack CreateStack();
void Push(Stack s, ElementType item);
int IsEmpty(Stack s);
ElementType Pop(Stack s);

Stack CreateStack()
{
     Stack stack = (Stack )malloc(sizeof(struct SNode));
     stack->Top = -1;
     return stack;
}
void Push(Stack s, ElementType item)
{
     s->Data[++s->Top] = item;
}
int IsEmpty(Stack s)
{
     if(s->Top == -1)
          return 1;
     else
          return 0;
}
ElementType Pop(Stack s)
{
     if(IsEmpty(s))
     {
          printf("the stack is Empty");
          return 0;
     }
     return s->Data[s->Top--];
}

bool isValid(char * a){
    Stack s = CreateStack();
    int i=0;
    while(a[i]!='\0')
    {
        if(IsEmpty(s))
        {
            Push(s, a[i]);
        }
        else
        {
            if(a[i] == ')' && s->Data[s->Top] == '(')  //此处如果无法获取栈顶元素,可以先弹出记录下来,后面再入栈
            {
               Pop(s);
            }
            else if(a[i] == ']' && s->Data[s->Top] == '[')
            {
                Pop(s);
            }
            else if(a[i] == '}' && s->Data[s->Top] == '{')
            {
                Pop(s);
            }
            else{
                Push(s, a[i]);
            }
        }
        i++;
    }
    if(IsEmpty(s))
    {
        return true;
    }
    return false;

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的贝塔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值