什么是堆栈
堆栈(Stack): 具有一定操作约束的线性表
- 只在一端(栈顶)进行插入、删除操作
- 插入数据:入栈(Push)
- 删除数据:出栈)(Pop)
- 后入先出:Last In First Out(LIFO)
堆栈的抽象数据类型描述
类型名称:堆栈Stack
数据对象集:一个有0个或多个元素的有穷线性表
操作集:长度未MaxSize的堆栈S,堆栈元素item(ElementType)
基本操作主要有:
- Stack CreateStack(int MaxSize): 生成空堆栈,其最大长度为Maxsize
- int IsFull(Stack S, int MaxSize): 判断堆栈S是否已满
- void Push(Stack S, ElementType item): 将元素item压入堆栈
- int IsEmpty(Stack S): 判断堆栈S是否为空
- 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;
}