一.栈的详细讲解
什么是栈,以及它又有怎样的特点呢?
1.栈的定义
栈是一个线性表,它仅可以在表尾进行插入或者删除操作。因此,对于栈来说,表尾端有着特殊含义,称为栈顶,相应地,表头端称为栈底。
2.栈的特点
栈又可称为后进先出(Last In First Out,LIFO)的线性表,也就是说如果一个数据先进入线性表,那么这个数据是最后离开线性表的。这个特点可用下图来展示:
在程序设计中,如果需要按照保存数据时相反的顺序来使用数据,则可以利用栈来实现。
下面是栈实现的代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack {
STDataType* a;
int top;// 栈顶
int kj;// 容量
}Stack;
// 初始化栈
void StackInit(Stack* pa);
// 销毁栈
void StackDestroy(Stack* pa);
// 入栈
void StackPush(Stack* pa, STDataType data);
// 出栈
void StackPop(Stack* pa);
// 获取栈顶元素
STDataType StackTop(Stack* pa);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* pa);
void StackInit(Stack* pa)
{
assert(pa);
pa->a = NULL;
pa->top = 0;
pa->kj = 0;
}
void StackDestroy(Stack* pa)
{
assert(pa);
free(pa->a);
pa->a= NULL;
pa->top = 0;
pa->kj = 0;
}
void StackPush(Stack* pa, STDataType data)
{
assert(pa);
if (pa->kj == pa->top)//空间不够,阔容
{
int newkj = pa->kj == 0 ? 4 : pa->kj * 2;
STDataType* mid = (STDataType*)realloc(pa->a, sizeof(STDataType) * newkj);
if (mid == NULL)
{
perror("realloc fail");
return;
}
pa->a = mid;
pa->kj = newkj;
}
pa->a[pa->top] = data;
pa->top++;
}
void StackPop(Stack* pa)
{
assert(pa);
assert(!BK(pa));
pa->top--;
}
STDataType StackTop(Stack* pa)
{
assert(pa);
assert(!StackEmpty(pa));
return pa->a[pa->top - 1];
}
int StackEmpty(Stack* pa)
{
assert(pa);
return pa->top == 0;
}
int main()
{
return 0;
}
二.括号匹配的检测
给定一个只包括 ('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
1.字符串有效的判断
字符串有效有以下特点:
(1)左括号必须用相同类型的右括号闭合。
(2)左括号必须以正确的顺序闭合。
(3)每个右括号都有一个对应的相同类型的左括号。
2.实现思路
遍历字符串s, 根据栈后进先出的特点,让左括号入栈,再出栈与下一个字符进行匹配。如果有一对不匹配,则直接停止匹配。
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack {
STDataType* a;
int top;// 栈顶
int kj;// 容量
}Stack;
// 初始化栈
void StackInit(Stack* pa);
// 销毁栈
void StackDestroy(Stack* pa);
// 入栈
void StackPush(Stack* pa, STDataType data);
// 出栈
void StackPop(Stack* pa);
// 获取栈顶元素
STDataType StackTop(Stack* pa);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* pa);
void StackInit(Stack* pa)
{
assert(pa);
pa->a = NULL;
pa->top = 0;
pa->kj = 0;
}
void StackDestroy(Stack* pa)
{
assert(pa);
free(pa->a);
pa->a= NULL;
pa->top = 0;
pa->kj = 0;
}
void StackPush(Stack* pa, STDataType data)
{
assert(pa);
if (pa->kj == pa->top)//空间不够,阔容
{
int newkj = pa->kj == 0 ? 4 : pa->kj * 2;
STDataType* mid = (STDataType*)realloc(pa->a, sizeof(STDataType) * newkj);
if (mid == NULL)
{
perror("realloc fail");
return;
}
pa->a = mid;
pa->kj = newkj;
}
pa->a[pa->top] = data;
pa->top++;
}
void StackPop(Stack* pa)
{
assert(pa);
assert(!BK(pa));
pa->top--;
}
STDataType StackTop(Stack* pa)
{
assert(pa);
assert(!StackEmpty(pa));
return pa->a[pa->top - 1];
}
int StackEmpty(Stack* pa)
{
assert(pa);
return pa->top == 0;
}
bool isValid(char* s) {
Stack sz;
StackInit(&sz);
while (*s) {
if (*s == '(' || *s == '{' || *s == '[') {//左括号入栈
StackPush(&sz, *s);
}
else {//左括号出栈匹配
if (StackEmpty(&sz)) {//栈为空,但字符串不为空,右括号多于左括号
return false;
}
char top = StackPop(&sz);//取栈里的左括号出来匹配
StackPop(&sz);
if ((*s == ')' && top != '(') || (*s == '}' && top != '{') ||
(*s == ']' && top != '[')) {
return false;//有一对不匹配就退出
}
}
++s;
}
bool ret = StackEmpty(&sz);//判断栈是否为空,如果不为空,则左括号多于右括号
return ret;
StackDestroy(&sz);
}
int main()
{
char s={'(',')','[',']','{','}'};
int r=isValid(s);
return 0;
}