数据结构学习之栈

本篇博客我们将深入学习数据结构中栈与队列相关的内容

作者的个人gitee:楼田莉子 (riko-lou-tian) - Gitee.com

目录

概念

栈的实现

初始化

销毁

入栈

判空

出栈

获取栈顶元素

栈的有效元素个数

源代码

与栈相关的算法题(力扣)有效的括号

​编辑


概念

栈是一种特殊的线性表,只允许在固定的一端进行插入删除元素的操作。进行数据插入和删除操作的一端叫栈顶,另一端叫栈底。遵循"后进先出"的原则。下图就是对栈后进先出的一种形象化演示。

栈的逻辑结构是线性的,物理结构因种类而决定。

压栈 :栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈 :栈的删除操作叫出栈。出数据也在栈顶

栈在底层上一般使用数组或者链表实现。通常是数组,因为数组插入数据的代价更小

栈的实现

stack.h------栈的结构定义和相关函数的声明

stack.c------相关函数的实现

test.c ------测试

初始化

cpp 复制代码
//初始化栈
void STInit(ST* st)
{
	st->arr = NULL;
	st->top = st->capacity = 0;
}

销毁

cpp 复制代码
//销毁栈
void STDestroy(ST* st)
{
	if (st->arr)
	{
		free(st->arr);
	}
	st->arr = NULL;
	st->top = st->capacity = 0;
}

入栈

cpp 复制代码
//入栈
void STPush(ST* st, STDataType data)
{
	if (st->top == st->capacity)
	{
		//增容
		int newcapacity = st->capacity==0? 4:st->capacity * 2 ;
		STDataType*tmp=(STDataType*)realloc(st->arr, newcapacity*sizeof(STDataType));
		if (tmp == NULL)
		{
			printf("内存分配失败!\n");
			exit(1);
		}
		st->arr = tmp;
		st->capacity = newcapacity;
	}
	st->arr[st->top++] = data;
}

判空

cpp 复制代码
//判断栈是否为空
bool STIsEmpty(ST* st)
{
	assert(st);
	return st->top == 0;
}

出栈

cpp 复制代码
//出栈
//栈不为空才能出栈
void STpop(ST* st)
{
	assert(!STIsEmpty(st));
	--st->top;
}

获取栈顶元素

cpp 复制代码
//获取栈顶元素
STDataType STGetTop(ST* st)
{
	assert(!STIsEmpty(st));
	return st->arr[st->top-1];
}

栈的有效元素个数

cpp 复制代码
//获取栈中有效元素个数
size_t STGetValidSize(ST* st)
{
	return st->top;
}

源代码

stack.h

cpp 复制代码
#pragma once
#include<stdio.h>
#include <stdlib.h>
#include<assert.h>
#include<stdbool.h>
//定义栈的数据类型
typedef int STDataType;
//定义栈的结构
typedef  struct Stack
{
	STDataType*arr;		// 栈底
	size_t top;    // 有效数据个数(栈顶)
	size_t capacity;// 栈的容量
}ST;
//初始化栈
void STInit(ST* st);
//入栈
void STPush(ST* st, STDataType data);
//判断栈是否为空
bool STIsEmpty(ST* st);
//出栈
void STpop(ST* st);
//获取栈顶元素
STDataType STGetTop(ST* st);
//获取栈中有效元素个数
size_t STGetValidSize(ST* st);
//销毁栈
void STDestroy(ST* st);

stack.c

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"stack.h"
//初始化栈
void STInit(ST* st)
{
	st->arr = NULL;
	st->top = st->capacity = 0;
}
//入栈
void STPush(ST* st, STDataType data)
{
	if (st->top == st->capacity)
	{
		//增容
		int newcapacity = st->capacity==0? 4:st->capacity * 2 ;
		STDataType*tmp=(STDataType*)realloc(st->arr, newcapacity*sizeof(STDataType));
		if (tmp == NULL)
		{
			printf("内存分配失败!\n");
			exit(1);
		}
		st->arr = tmp;
		st->capacity = newcapacity;
	}
	st->arr[st->top++] = data;
}
//判断栈是否为空
bool STIsEmpty(ST* st)
{
	assert(st);
	return st->top == 0;
}
//出栈
//栈不为空才能出栈
void STpop(ST* st)
{
	assert(!STIsEmpty(st));
	--st->top;
}
//获取栈顶元素
STDataType STGetTop(ST* st)
{
	assert(!STIsEmpty(st));
	return st->arr[st->top-1];
}
//获取栈中有效元素个数
size_t STGetValidSize(ST* st)
{
	return st->top;
}
//销毁栈
void STDestroy(ST* st)
{
	if (st->arr)
	{
		free(st->arr);
	}
	st->arr = NULL;
	st->top = st->capacity = 0;
}

test.c

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"stack.h"
void test1()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);	
	STPush(&st, 3);
	STPush(&st, 4);
	STPush(&st, 5);
	//STpop(&st);
	while (!STIsEmpty(&st))
	{
		int top= STGetTop(&st);
		printf("%d ", top);
		STpop(&st);
	}
}
int main()
{
	test1();
	return 0;
}

与栈相关的算法题(力扣)有效的括号

由上图示例可知:括号没有括号的优先级但是有闭合的顺序

思路:借助栈来实现

遍历字符串,(入栈,)取栈顶与字符比较是否匹配

答案:

cpp 复制代码
//借助数据结构------栈
//定义栈的数据类型
typedef char STDataType;
//定义栈的结构
typedef  struct Stack
{
	STDataType*arr;		// 栈底
	size_t top;    // 有效数据个数(栈顶)
	size_t capacity;// 栈的容量
}ST;
//初始化栈
void STInit(ST* st)
{
	st->arr = NULL;
	st->top = st->capacity = 0;
}
//入栈
void STPush(ST* st, STDataType data)
{
	if (st->top == st->capacity)
	{
		//增容
		int newcapacity = st->capacity==0? 4:st->capacity * 2 ;
		STDataType*tmp=(STDataType*)realloc(st->arr, newcapacity*sizeof(STDataType));
		if (tmp == NULL)
		{
			printf("内存分配失败!\n");
			exit(1);
		}
		st->arr = tmp;
		st->capacity = newcapacity;
	}
	st->arr[st->top++] = data;
}
//判断栈是否为空
bool STIsEmpty(ST* st)
{
	assert(st);
	return st->top == 0;
}
//出栈
//栈不为空才能出栈
void STpop(ST* st)
{
	assert(!STIsEmpty(st));
	--st->top;
}
//获取栈顶元素
STDataType STGetTop(ST* st)
{
	assert(!STIsEmpty(st));
	return st->arr[st->top-1];
}
//获取栈中有效元素个数
size_t STGetValidSize(ST* st)
{
	return st->top;
}
//销毁栈
void STDestroy(ST* st)
{
	if (st->arr)
	{
		free(st->arr);
	}
	st->arr = NULL;
	st->top = st->capacity = 0;
}
//栈实现的代码
bool isValid(char* s) 
{
    ST st;
    STInit(&st);
    char*pi=s;
    while(*pi!='\0')
    {
        //左括号入栈
        if(*pi=='('||*pi=='['||*pi=='{')
        {
            STPush(&st,*pi);
        }
        else
        {
            //判断为空的情况
            if(STIsEmpty(&st))
            {
                STDestroy(&st);
                return false;
            }
            //右括号出栈
            //取栈顶跟*pi比较进行匹配
            char top=STGetTop(&st);
            if((top=='('&&*pi!=')')
            ||(top=='['&&*pi!=']')
            ||(top=='{'&&*pi!='}'))
            {
                STDestroy(&st);
                return false;
            }
            STpop(&st);
        }
        
        pi++;
    }
    bool ret =STIsEmpty(&st)?true:false;
    STDestroy(&st);
    return ret;
}

本篇内容就到这里了,喜欢的话请给个点赞谢谢

封面图自取:

相关推荐
long3162 分钟前
K‘ 未排序数组中的最小/最大元素 |期望线性时间
java·算法·排序算法·springboot·sorting algorithm
进击的小头5 分钟前
FIR滤波器实战:音频信号降噪
c语言·python·算法·音视频
xqqxqxxq10 分钟前
洛谷算法1-1 模拟与高精度(NOIP经典真题解析)java(持续更新)
java·开发语言·算法
razelan10 分钟前
初级算法技巧 4
算法
砍树+c+v11 分钟前
3a 感知机训练过程示例(手算拆解,代码实现)
人工智能·算法·机器学习
zy_destiny12 分钟前
【工业场景】用YOLOv26实现4种输电线隐患检测
人工智能·深度学习·算法·yolo·机器学习·计算机视觉·输电线隐患识别
鲨辣椒1008613 分钟前
二叉树代码变现——递归函数实现深度遍历
数据结构
别了,李亚普诺夫16 分钟前
数字测速方法和PID控制
笔记·学习·电机
放氮气的蜗牛18 分钟前
从头开始学习AI:第五章 - 多分类与正则化技术
人工智能·学习·分类
智驱力人工智能22 分钟前
货车违规变道检测 高速公路安全治理的工程实践 货车变道检测 高速公路货车违规变道抓拍系统 城市快速路货车压实线识别方案
人工智能·opencv·算法·安全·yolo·目标检测·边缘计算