概述
栈和队列比较简单,就简单的描述描述,上一节链表讲的有点多了,这次简单讲解一下栈和对列。
4.1 栈
4.1.1 栈的结构
栈的结构,在其他博客也说的很多了,这里就简单说一说,栈是一种线性结构,栈的元素只能先进后出(Frist In Last Out简称 FILO),最早进入的元素存储到栈底,最后进入的元素叫栈顶,栈的操作只能在栈顶操作。
栈的结构可以用数组或者链表来实现
下面只要用数组来实现的:
typedef struct Stack
{
int top; //栈顶指针
int size; //栈的大小
Elemtype *data; //栈的元素
}_Stack;
4.1.2 栈的操作
- 入栈
入栈操作(push)就是把一个新的元素添加到栈顶的位置,然后这个新元素就是栈顶了。
/**
* @brief 入栈,内部支持扩容
* @param
* @retval
*/
int stack_push(struct Stack *s, Elemtype data)
{
if(s == NULL)
return -1;
if(s->top >= s->size) //这个是要等于,因为有0
{
int new_len = (s->size>>1) + s->size;
//printf("len = %d %d %dn", s->size>>1, s->size, new_len);
s->data = realloc(s->data, new_len*sizeof(Elemtype)); //扩容1.5倍,realloc可以复制之前数据到新的内容区
if(s == NULL)
return -2;
s->size = new_len;
}
s->data[s->top] = data;
s->top++;
return 0;
}
- 出栈
出栈操作(pop)就是把元素从栈里取出,不过只能从栈顶的元素取出,出栈元素的前一个元素将会称为新的栈顶
/**
* @brief 出栈,
* @param
* @retval
*/
int stack_pop(struct Stack *s, Elemtype *data)
{
if(s == NULL || data == NULL)
return -1;
//可以做减少容量的操作
if(s->top == 0)
return -2;
*data = s->data[--s->top]; //这个是指向栈顶的,需要先减
return 0;
}
4.1.3 附加:栈的面试题
1.有效括号
leetcode 20题:
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
这道题是在leetcode做的第一道题,不过感觉c语言刷leetcode有点累,啥都需要封装,但是目前涉及到这些基本的数据结构,还是用c写,在leetcode可以用c++,直接调用c++封装好的栈。之前我们也封装好了一个栈,可以现在用来试试。
这道题目就是利用了栈的功能,先进后出,我们把每进来的属于左括号的都进栈,当来了右括号的,就把获取栈顶元素,判断一下是否和刚进来的右括号匹配,如果不匹配,就返回失败,如果匹配的话,出栈,然后继续下一轮。
代码:
/**
* @brief 有效括号
* @param s: 字符串
* @retval
*/
int stack_ValidParentheses(char *s)
{
//1.创建一个栈
struct Stack st;
stack_creat(&st, 10);
//2.分解字符串,c语言只能用指针遍历
char *c = s;
while(*c != '