前言
当你使用浏览器上网时,几乎所有的浏览器都有一个后退键,你点击后可以按照访问顺序的逆序回到之前加载过的网页,生活中有许多类似的操作,利用word的撤销,他们的原理就是我们接下来介绍的一种数据结构–栈。
一、什么是栈?
栈的定义:栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
我们将允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为**后进先出(Last In First Out)**的线性表,简称LIFO结构。
二、栈的特点与栈的操作
1.栈的特点
正如上面文章所说栈的特点就是仅能对表尾进行操作,栈始终只在栈顶进行操作,这也就使得:栈底是固定的,最先进入的数据只能在栈底。但最先进栈的元素不一定是最后出栈的。
举个例子:现在我们让1,2,3三个整形元素依次进栈,会有哪些进栈次序呢?
第一种:1,2,3进,3,2,1出,这是我们最容易想到的一种。
第二种:1进,1出,2进,2出,3进,3出。即出一个进一个,最先进栈的1最先出去了。
还有几种方案,在此就不一一列举。
下面给大家介绍一下栈的基本操作。
2.栈的基本操作:
栈的基本操作有两种:进栈和入栈,我们也可以通俗的把它理解为子弹的压入与弹出。
首先我们对栈定义(顺序存储栈)。
代码如下(示例):
#include<stdio.h>
#define MAXSIZE 100;
typedef struct {
int data[MAXSIZE]; //用数组作为栈的存储空间
int top; //top作为栈顶指针
}stack;
此处是用数组虚拟栈。
进栈操作----push。
进栈操作,即为插入,也称为压栈,入栈,即使新元素加入栈顶,首先我们应该判断栈是否已满,若未满,才可进行插入操作。判断栈满的条件未top == maxsize - 1。
代码如下(示例):
int push(stack *s, int val) { //val为入栈数据
if (s->top == MAXSIZE - 1) { //此时栈已满,无法入栈。
return 0;
}
s->top++; //栈顶指针指向新的栈顶。
s->data[s->top] = val; //新元素入栈。
return 1;
}
出栈操作----pop。
出栈操作,即为删除,也称为弹栈,我们进行出栈操作时,应判断栈中是否有元素,若无元素栈顶指针top指向栈底,即top == -1;
代码如下(示例):
int pop(stack *s, int *val) { //将弹出的栈顶元素赋给val。
if (s->top == -1) { //此时栈为空。
return 0;
}
*val = s->data[s->top];
s->top; //栈顶指针减一
return 1;
}
}
关于顺序栈的应用——有效的括号
题目. 有效的括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"输出:true
示例 2:
输入:s = "()[]{}"输出:true
示例 3:
输入:s = "(]"输出:false
示例 4:
输入:s = "([)]"输出:false
示例 5:
输入:s = "{[]}"输出:true
提示:
1 <= s.length <= 104
s 仅由括号 ‘()[]{}’ 组成
代码如下(示例):
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char pairs(char a) {
if (a == ')') return '(';
if (a == '}') return '{';
if (a == ']') return '[';
return 0;
}
int isValid(char * s) {
int length , i;
length = strlen(s);
if (length % 2 == 1) {
return 0;
}
int stack[length + 1] , top = 0;
for(i = 0;i < length; i++){
char ch = pairs(s[i]);
if(ch) {
if(top == 0 || stack[top - 1] != ch) {
return 0;
}
top--;
} else{
stack[top++] = s[i];
}
}
if (top == 0) {
return 1;
}
if (top != 0) {
return 0;
}
}
int main(void) {
char str1[100];
scanf("%s",str1);
int a = isValid(str1);
if (a == 0) {
printf("false");
} else {
printf("true");
}
}
总结
第一次写博客,有许多地方可能存在瑕疵。
虽然大多数我们使用的都是虚拟栈,但栈是一种思想,栈的引入简化了程序设计的问题,划分不同关注层次,使得我们更集中与问题的核心。