栈PART 1

目录

[1. 栈](#1. 栈)

[1.1 栈的概念和结构](#1.1 栈的概念和结构)

[1.2 栈的实现](#1.2 栈的实现)

[1.2.1 栈的顺序储存结构](#1.2.1 栈的顺序储存结构)

[1.2.2 栈的基本操作](#1.2.2 栈的基本操作)

[1.3 有效的括号](#1.3 有效的括号)


1. 栈

1.1 栈的概念和结构

堆栈又名栈(stack),它是一种运算受限的线性表。

限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。

向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;

从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

入数据在栈顶,出数据也在栈顶。

1.2 栈的实现

栈的实现一般可以使用数组或者链表来实现,两者相比较的话,数组的结构实现更优。

1.2.1 栈的顺序储存结构

cpp 复制代码
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

1.2.2 栈的基本操作

(1)初始化

cpp 复制代码
//Stack.h

//初始化
void STInit(ST* ps);
cpp 复制代码
//Stack.c

void STInit(ST* ps)
{
	assert(ps);

	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

注意:这里 top 的值可以是0,或者是-1。

两种写法的区别在于:

这两种写法没有好坏之分。

(2)销毁

cpp 复制代码
//Stack.h

//销毁
void STDestroy(ST* ps);
cpp 复制代码
//Stack.c

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

(3)入栈

cpp 复制代码
//Stack.h

//入栈
void STPush(ST* ps, STDataType x);
cpp 复制代码
//Stack.c

void STPush(ST* ps, STDataType x)
{
	assert(ps);
    //如果栈满,扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		ps->a = tmp;
		ps->capacity = newcapacity;  //更新栈的容量
	}

	ps->a[ps->top] = x;
	ps->top++;  //将元素x插入栈中,并且将栈顶指针上移一位
}

(4)出栈

cpp 复制代码
//Stack.h

//出栈
void STPop(ST* ps);
cpp 复制代码
//Stack.c

void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));  //栈不为空

	ps->top--;  //栈顶指针向后移一位
}

(5)读取栈顶元素

cpp 复制代码
//Stack.h

//读取栈顶元素
STDataType STTop(ST* ps);
cpp 复制代码
//Stack.c

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	return ps->a[ps->top - 1];  //因为前面定义的 top = 0
}

(6)返回栈的长度

cpp 复制代码
//Stack.h

//返回栈的长度
int STSize(ST* ps);
cpp 复制代码
//Stack.c

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

(7)判断栈是否为空

cpp 复制代码
//Stack.h

//判断栈是否为空
bool STEmpty(ST* ps);
cpp 复制代码
//Stack.c

bool STEmpty(ST* ps)
{
	assert(ps);
    if(ps->top == 0)
        return true;
    else
        return false;
}

1.3 有效的括号

示例代码:

cpp 复制代码
typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

//初始化
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);

//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);

//读取栈顶元素
STDataType STTop(ST* ps);

//栈的大小
int STSize(ST* ps);

//判断栈是否为空
bool STEmpty(ST* ps);

void STInit(ST* ps)
{
	assert(ps);

	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);

	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		ps->a = tmp;
		ps->capacity = newcapacity;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	ps->top--;
}

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}

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((*s == ']' && top != '[')
             || (*s == ')' && top != '(')
             || (*s == '}' && top != '{'))
            {
                STDestroy(&st);
                return false;
            }
        }

        ++s;
    }
    //左括号比右括号多,栈不为空
    bool ret = STEmpty(&st);
    STDestroy(&st);
    return ret;
}
相关推荐
是翔仔呐6 分钟前
第10章 串口通信USART全解:轮询/中断/DMA三种收发模式与上位机通信实战
c语言·开发语言·stm32·单片机·嵌入式硬件·学习·gitee
计算机安禾19 分钟前
【数据结构与算法】第12篇:栈(二):链式栈与括号匹配问题
c语言·数据结构·c++·学习·算法·visual studio code·visual studio
散峰而望28 分钟前
【数据结构】单调栈与单调队列深度解析:从模板到实战,一网打尽
开发语言·数据结构·c++·后端·算法·github·推荐算法
旖-旎36 分钟前
位运算(两整数之和)(3)
c++·算法·leetcode·位运算
杨校37 分钟前
杨校老师课堂备战C++之数据结构中栈结构专题训练
开发语言·数据结构·c++
keyborad pianist1 小时前
数据结构
数据结构·学习
AI科技星1 小时前
基于v≡c光速螺旋理论的正确性证明:严格遵循科学方法论的完整路径
c语言·开发语言·人工智能·线性代数·算法·机器学习·数学建模
浅念-7 小时前
Linux 开发环境与工具链
linux·运维·服务器·数据结构·c++·经验分享
潜创微科技--高清音视频芯片方案开发9 小时前
2026年C转DP芯片方案深度分析:从适配场景到成本性能的优选指南
c语言·开发语言
青桔柠薯片11 小时前
从C语言到裸机运行:i.MX6ULL 的 GPIO 控制与编译链接过程分析
c语言·开发语言·imx6ull