栈的基本操作

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk

      ⸝⋆   ━━━┓
     - 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code
┗━━━━━━━  ➴ ⷯ

本人座右铭 :   欲达高峰,必忍其痛;欲戴王冠,必承其重。

👑💎💎👑💎💎👑 
💎💎💎自💎💎💎
💎💎💎信💎💎💎
👑💎💎 💎💎👑    希望在看完我的此篇博客后可以对你有帮助哟

👑👑💎💎💎👑👑   此外,希望各位大佬们在看完后,可以支持一下。
👑👑👑💎👑👑👑


目录:
一:初始化
二:销毁
三:进栈(入栈 / 压栈)
四:出栈
五:获取栈顶元素
六:求栈中元素个数
七:判空
八:练习

栈的基本了解: 栈的概念和结构:

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。
栈中的数据元素遵守后进先出LIFOLast In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除操作叫做出栈。出数据也在栈顶
1:初始化

在对栈进行初始化之前需要先对栈这个结构进行定义一下

这里暂且就以 数组栈为例

typedef int STDataType;
typedef struct Stack {
	STDataType* a;//动态的
	int capacity;//容量
	int top;//记录栈顶位置
}ST;

初始化:让 capacity = 0,至于 top 是为0 还是为 1,自行决定 

void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;//表示 top  指向栈顶元素下一个位置
	//pst->top = -1;//表示 top  指向栈顶元素的位置
}
2:销毁

这个就很简单了,直接对 数组进行销毁即可

3:进栈(入栈 / 压栈)

注意: 初始化 top 的值  对进栈的操作很重要

top = 0 :top 指向栈顶元素下一个的位置

top =  0 ,此时进栈需要 先把数据插到 top  对应的位置,之后top++ 

top = 0 :刚好也可以表示 栈中数据元素个数为 0

top = -1 :top 指向 栈顶元素位置

top = -1:

进栈的操作:先让top++;再对top 所在地位置进行插入数据 

void STPush(ST* pst, STDataType x)
{
	assert(pst);
	//空间检查
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
			return;
		//成功
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top] = x;
	pst->top++;//指向栈顶元素下一个位置
}
4:出栈

直接一步到位即可;让top - - 

注意不是 top -1

void STPop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));//判空
	pst->top--;
}
5:获取栈顶元素
STDataType STTop(ST* pst)//获取栈顶元素
{
	assert(pst);
	return pst->a[pst->top-1];// 注意top 永远指向栈顶元素下一个位置
}
6:求栈中元素个数
int STSize(ST* pst)//求栈中元素个数
{
	assert(pst);
	return pst->top;
}
7:判空 
bool STEmpty(ST* pst)
{
	assert(pst);
	/*if (pst->top == 0)
	{
		return true;
	}
	else
		return false;*/
	return pst->top == 0;//不用三目操作符
}
完整代码:
 test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack.h"

void test()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	//STPrint(&st);//注意没有这种写法
	//对于栈的访问都是边访问边出栈
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	STPush(&st, 5);
	STPush(&st, 6);
	int size = STSize(&st);
	while (!STEmpty(&st))
	{
		printf("%d ", STTop(&st));//获取栈顶元素
		STPop(&st);//出栈
	}
	STDestroy(&st);


}
int main()
{
	test();
	return  0;
}
Stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"

void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;//表示 top  指向栈顶元素下一个位置
	//pst->top = -1;//表示 top  指向栈顶元素的位置
}
void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
}

void STPush(ST* pst, STDataType x)
{
	assert(pst);
	//空间检查
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
			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);
	return pst->a[pst->top-1];// 注意top 永远指向栈顶元素下一个位置
}

int STSize(ST* pst)//求栈中元素个数
{
	assert(pst);
	return pst->top;
}

bool STEmpty(ST* pst)
{
	assert(pst);
	/*if (pst->top == 0)
	{
		return true;
	}
	else
		return false;*/
	return pst->top == 0;//不用三目操作符
}
Stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int STDataType;
typedef struct Stack {
	STDataType* a;//动态的
	int capacity;//容量
	int top;//记录栈顶位置
}ST;

void STInit(ST* pst);
void STDestroy(ST* pst);

void STPush(ST* pst, STDataType x);
void STPop(ST* pst);

STDataType STTop(ST* pst);//获取栈顶元素

int STSize(ST* pst);//求栈中元素个数

bool STEmpty(ST* pst);

 8:练习

刚刚好学了栈,那咱就趁热打铁练习一下 

分析:

当是左括号中的 {   (     [   任一个,我们就进栈  ;若是出现对应的右括号中的任一个我们就去栈顶元素进行匹配 若是 左右括号不能匹配成功则  return  false;

 注意一些细节:

1)

数组里面只有左括号或者是只有右括号时逻辑 的实现

2)只有右括号的情况: 此时栈中元素个数为0

char top;  // 用来保留当前栈中元素

            if (STEmpty(&st))

            {

                STDestroy(&st);

                return false;  // 匹配失败

            }            

3)正常情况:

else

            {

                top = STTop(&st);

                STPop(&st);  出栈顶元素,保证不为空

}

 OJ代码:
typedef char STDataType;
typedef struct Stack {
	STDataType* a;//动态的
	int capacity;//容量
	int top;//记录栈顶位置
}ST;

void STInit(ST* pst);
void STDestroy(ST* pst);

void STPush(ST* pst, STDataType x);
void STPop(ST* pst);

STDataType STTop(ST* pst);//获取栈顶元素

int STSize(ST* pst);//求栈中元素个数

bool STEmpty(ST* pst);
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;//表示 top  指向栈顶元素下一个位置
	//pst->top = -1;//表示 top  指向栈顶元素的位置
}
void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
}

void STPush(ST* pst, STDataType x)
{
	assert(pst);
	//空间检查
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
			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];// 注意top 永远指向栈顶元素下一个位置
}

int STSize(ST* pst)//求栈中元素个数
{
	assert(pst);
	return pst->top;
}

bool STEmpty(ST* pst)
{
	assert(pst);
	/*if (pst->top == 0)
	{
		return true;
	}
	else
		return false;*/
	return pst->top == 0;//不用三目操作符
}


bool isValid(char* s)
{
	/*
	左括号入栈
	右括号与栈顶元素进行匹配 :成功就出栈
	*/
	ST st;//定义一个栈
	STInit(&st);
	while (*s)
	{
		//*s 不是左括号就是右括号
		if (*s == '['
			|| *s == '{'
			|| *s == '('
			)
		{
			STPush(&st, *s);
		}
		else
		{
			char top;
			if (STEmpty(&st))
			{
				STDestroy(&st);
				return false;
			}
			else
			{
				top = STTop(&st);
				STPop(&st);   出栈顶元素,保证不为空
			}
			if (
				*s == ']' && top != '['
				|| *s == '}' && top != '{'
				|| *s == ')' && top != '('
				)
			{
				STDestroy(&st);
				return false;//不匹配
			}
		}
		s++;
	}
	bool  ret = STEmpty(&st);
	STDestroy(&st);
	//return true;//出循环匹配成功伴随栈为空,非空级失败
	return ret;
}
结语:

以上就是我今日要share 的,总体来说很简单相较于链表那块,轻松拿捏。有些事情看似简单易懂,但只有当自己真正去实践才知道,常言道:纸上得来终觉浅,绝知此事要躬行!同时在今天这个特别 的日子里也是祝愿大家新春快乐,在新的一年里快快乐乐,在学习上工作上一帆风顺

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值