目录
一、栈的概念及结构
二、栈的实现
1、声明栈结构体
2、初始化
3、 销毁
4、 入栈(压栈)
5、出栈(弹栈)
6、栈的大小
OJ练习
完整版:
Stack.h声明
Stack.c函数
test.c参考测试用例
栈(Stack)是一种常见的数据结构,它遵循一种特定的数据存储和访问方式,通常用于管理数据的后进先出(Last-In-First-Out,LIFO)的操作顺序。这意味着最后压入栈的元素将首先被弹出,类似于一叠盘子,你总是在最上面放入和拿出盘子。
栈通常支持以下两种基本操作:
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小,(CPU高速缓存命中率会更高)
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
void STDestroy(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
void STPush(ST* pst,STDataType x)
{
if (pst->top == pst->capacity) {
int newCapacity = pst->capacity == 0 ? 4 :pst-> capacity * 2;
STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
if (tmp == NULL) {
perror("realloc fail");
return;
}
pst->a = tmp;
pst->capacity = newCapacity;
}
pst->a[pst->top] = x;
pst->top++;
}
- 第一次入栈时,新栈newCapacity的容量为4,然后为其开辟相应大小的空间,
- 如果已满即top与capacity相等,则新栈newCapacity的大小为当前的两倍,然后对当前空间进行扩容。
出栈需要三个函数,
STPop
用于弹出元素,STTop
用于获取栈顶元素的值,而STEmpty
用于检查栈是否为空。
void STPop(ST* pst)
{
assert(pst);
assert(!STEmpty(pst));
pst->top--;
}
STDataType STTop(ST* pst)
{
assert(pst);
assert(!STEmpty(pst));
return pst->a[pst->top - 1];
}
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
void STPop(ST* pst)
函数:
- 这个函数用于弹出栈顶元素,也就是将栈顶位置
pst->top
的值减一,相当于将栈顶元素从栈中移除。assert(pst)
确保传入的pst
指针不为空。assert(!STEmpty(pst))
确保栈不为空,因为如果栈已经为空,就不应该执行弹出操作,否则会导致错误。pst->top--;
将栈顶位置减一,以实现弹出操作。
STDataType STTop(ST* pst)
函数:
- 这个函数用于获取栈顶元素的值,但不将其从栈中移除。
assert(pst)
确保传入的pst
指针不为空。assert(!STEmpty(pst))
确保栈不为空,因为如果栈为空,就不能安全地访问栈顶元素。return pst->a[pst->top - 1];
返回栈顶位置pst->top
上的元素值,由于栈是从0开始索引的,所以需要减一。
bool STEmpty(ST* pst)
函数:
- 这个函数用于检查栈是否为空。
assert(pst)
确保传入的pst
指针不为空。return pst->top == 0;
返回一个布尔值,表示栈是否为空。如果栈顶位置pst->top
等于0,说明栈为空,返回true
;否则返回false
。
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
pst->top
的值。栈顶位置表示栈中元素的数量,因为栈是从0开始索引的,所以 pst->top
的值等于栈中元素的数量。20. 有效的括号
由于我们用C语言做这道题,所以代码前要加上咱们实现的栈的代码,同时要将数据类型STDataType改为char类型。
typedef char STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
void STDestroy(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
void STPush(ST* pst,STDataType x)
{
if (pst->top == pst->capacity) {
int newCapacity = pst->capacity == 0 ? 4 :pst-> capacity * 2;
STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
if (tmp == NULL) {
perror("realloc fail");
return;
}
pst->a = tmp;
pst->capacity = newCapacity;
}
pst->a[pst->top] = x;
pst->top++;
}
void STPop(ST* pst)
{
assert(pst);
assert(!STEmpty(pst));
pst->top--;
}
STDataType STTop(ST* pst)
{
assert(pst);
assert(!STEmpty(pst));
return pst->a[pst->top - 1];
}
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
bool isValid(char* s) {
ST st;
STInit(&st);
while (*s) {
if (*s == '(' || *s == '[' || *s == '{') {
STPush(&st, *s);
}
else {
if (STEmpty(&st)) {
STDestroy(&st);
return false;
}
char top = STTop(&st);
STPop(&st);
if ((top != '(' && *s == ')') ||
(top != '{' && *s == '}') ||
(top != '[' && *s == ']')) {
STDestroy(&st);
return false;
}
}
s++;
}
bool ret = STEmpty(&st);
STDestroy(&st);
return ret;
}
首先,创建一个名为 st
的 ST
结构体实例,并使用 STInit
初始化它。
s
中的每个字符。检查栈是否为空,如果为空,表示没有对应的左括号,则销毁栈,返回
false
。否则,弹出栈顶元素,将其与当前右括号进行匹配。如果不匹配,则销毁栈,返回
false
。
true
,否则返回 false
。STDestroy
销毁栈,并返回最终的匹配结果。#include
#include
#include
#include
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);
#include "Stack.h"
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
void STDestroy(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->top = 0;
pst->capacity = 0;
}
void STPush(ST* pst,STDataType x)
{
if (pst->top == pst->capacity) {
int newCapacity = pst->capacity == 0 ? 4 :pst-> capacity * 2;
STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
if (tmp == NULL) {
perror("realloc fail");
return;
}
pst->a = tmp;
pst->capacity = newCapacity;
}
pst->a[pst->top] = x;
pst->top++;
}
void STPop(ST* pst)
{
assert(pst);
assert(!STEmpty(pst));
pst->top--;
}
STDataType STTop(ST* pst)
{
assert(pst);
assert(!STEmpty(pst));
return pst->a[pst->top - 1];
}
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
#include "Stack.h"
void test1()
{
ST st;
STInit(&st);
STPush(&st, 999);
STPush(&st, 99);
STPush(&st, 9);
//printf("%d ", STTop(&st));
//STPop(&st);
//printf("%d ", STTop(&st));
while (!STEmpty(&st)) {
printf("%d ", STTop(&st));
STPop(&st);
}
STDestroy(&st);
}
int main()
{
test1();
return 0;
}