【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈)

这篇具有很好参考价值的文章主要介绍了【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

=========================================================================

相关代码gitee自取

C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期

【数据结构初阶】四、线性表里的链表(带头+双向+循环 链表 -- C语言实现)_高高的胖子的博客-CSDN博客

 =========================================================================

                     

1 . 栈(Stack)

栈的概念和结构:

栈的概念

  • 一种特殊的线性表,其只允许在固定的一端进行插入删除元素操作
                       
  • 进行数据插入和删除操作的一端 称为栈顶另一端称为栈底
                    
  • 栈中的数据元素遵守
    后进先出LIFO -- Last In First Out)的原则 -- 后进入的元素会先出来

               

压栈和出栈

  • 栈的插入操作叫做进栈/压栈/入栈 -- Push
    入数据栈顶
                   
  • 栈的删除操作叫做出栈 -- Pop
    出数据也在栈顶

                    

栈的结构

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

2 . 栈的实现

                   

使用 顺序表(数组) 或 链表(链式结构) 都可以实现栈

使用链表的话,可以使用 尾插(头插)  尾删(头删) 实现 栈的“后进先出”

尾插 -- 压栈        ;      尾删 -- 出栈

使用顺序表同样可以使用 尾插 尾删 实现

顺序表尾插和尾删操作效率较高处理数据时的缓存利用率也较高

所以下面用顺序表(数组)实现栈

               

(详细解释在图片的注释中,代码分文件放下一标题处)

               

实现具体功能前的准备工作

  • 包含之后会用到的头函数
                               
  • 创建栈数据类型 -- 栈中存储数据的类型
                 
  • 创建栈结构体(类型) -- 类型中应有控制栈内元素指针栈顶值栈大小
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

STInit函数 -- 对栈类型进行初始化

  • assert断言栈类型指针不为空
               
  • 栈内元素控制指针置为空
    栈容量(大小)置为0
    栈顶值定义为0
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

STDestroy函数 -- 销毁栈类型

  • assert断言栈类型指针不为空
               
  • 释放栈内元素控制指针置空
    栈容量置为0
    栈顶值置为0
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

STPush函数 -- 进行压栈

  • assert断言栈类型指针不为空
               
  • 为栈开辟动态空间进行检查
                 
  • 开辟成功后栈内元素控制指针指向开辟的空间
    重新设置capacity栈容量
                   
  • 压栈的值x放入栈
                 
  • 调整栈顶值“下标”top位置
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

STPop函数 -- 进行出栈

  • assert断言栈类型指针不为空
    assert断言栈不为空
               
  • 栈顶向下移动一个单位即可实现“删除”出栈
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

STTop函数 -- 获取栈顶元素

  • assert断言栈类型指针不为空
    assert断言栈不为空

               
  • 返回栈顶元素
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

STSize函数 -- 计算栈中元素个数

  • assert断言栈类型指针不为空
               
  • 返回top,即栈中元素个数
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

STEmpty函数 -- 判断栈是否为空

  • assert断言栈类型指针不为空
               
  • 判断top栈顶值是否为空
    返回true返回false
图示

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

            

            

---------------------------------------------------------------------------------------------

            

总体测试:

【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈),CCC全是C,数据结构,算法,c语言

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

3 . 对应代码

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 top;
	//类似于数组下标

	//栈存放数据容量(栈的大小):
	int capacity;

}ST; //重命名为ST


//静态顺序表:
//define N 10
//struct Stack
//{
//	int a[N];
//	int top;
//};


//初始化栈函数 -- 对栈类型进行初始化
//接收栈类型指针
void STInit(ST* ps);

//销毁栈函数 -- 销毁栈类型
//接收栈类型指针
void STDestroy(ST* ps);

//因为只有压栈和出栈操作
//只操作栈顶元素,所以没有
//头插(尾插)头删(头删)等其他操作

//压栈函数 -- 进行压栈
//接收栈类型指针(ps)、进行压栈的值(x)
void STPush(ST* ps, STDataType x);

//出栈函数 -- 进行出栈
//接收栈类型指针
void STPop(ST* ps);

//栈顶元素函数 -- 获取栈顶元素
//接收栈类型指针
STDataType STTop(ST* ps);

//栈中元素函数 --计算栈中元素个数
//接收栈类型指针
int STSize(ST* ps);

//判空函数 -- 判断栈是否为空
//接收栈类型指针
bool STEmpty(ST* ps);

            

            

---------------------------------------------------------------------------------------------

                文章来源地址https://www.toymoban.com/news/detail-717285.html

Stack.c -- 栈函数实现文件

#define _CRT_SECURE_NO_WARNINGS 1

//包含栈头文件:
#include "Stack.h"

//初始化栈函数 -- 对栈类型进行初始化
//接收栈类型指针
void STInit(ST* ps)
{
	//assert断言栈类型指针不为空:
	assert(ps != NULL);

	//将栈内元素控制指针置为空:
	ps->a = NULL;
	//将栈容量(大小)置为0:
	ps->capacity = 0;
	//将栈顶值定义为0:
	ps->top = 0;
}



//销毁栈函数 -- 销毁栈类型
//接收栈类型指针
void STDestroy(ST* ps)
{
	//assert断言栈类型指针不为空:
	assert(ps != NULL);

	//释放栈内元素控制指针:
	free(ps->a);
	//并将其置为空:
	ps->a = NULL;
	//栈容量置为0:
	ps->capacity = 0;
	//栈顶值置为0:
	ps->top = 0;
}



//压栈函数 -- 进行压栈
//接收栈类型指针(ps)、进行压栈的值(x)
void STPush(ST* ps, STDataType x)
{
	//assert断言栈类型指针不为空:
	assert(ps != NULL);

	//为栈开辟动态空间:
	if (ps->top == ps->capacity)
		//栈顶值 等于 栈大小
		//说明空间不够,需要扩容
	{
		//只有压栈时容量会增大可能需要扩容
		//只有这个函数会进行扩容操作,
		//所以没必要单独写一个扩容函数
		
		//进行扩容:
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		//因为栈容量capacity初始化为0,
		//所以可以使用三目操作符进行增容:
		//ps->capacity == 0 ? 4 : ps->capacity * 2
		//如果为0则直接增容到4,不为0则增容2倍
	
		//开辟动态空间:
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType)*newCapacity);
		//这里直接使用realloc进行动态空间开辟
		//如果realloc函数接收头指针(第一个参数)为空,
		//那么它的作用相当于malloc函数

		//对开辟空间进行检查:
		if (tmp == NULL)
			//返回空指针,开辟失败:
		{
			//打印错误信息:
			perror("realloc fail");
			//终止程序:
			exit(-1);
		}

		//开辟成功后,
		//栈内元素控制指针指向开辟空间:
		ps->a = tmp;
		
		//重新设置capacity栈容量:
		ps->capacity = newCapacity;
	}

	//将压栈的值(x)放入栈:
	ps->a[ps->top] = x; 
	//上面以a为头开辟连续的空间,
	//所以a可以看作一个数组名使用(?)
	//通过数组下标放入值
	
	//再调整栈顶值“下标”位置:
	ps->top++;
}



//出栈函数 -- 进行出栈
//接收栈类型指针
void STPop(ST* ps)
{
	//assert断言栈类型指针不为空:
	assert(ps != NULL);
	//assert断言栈顶top到了栈底就不能继续出栈了
	assert(ps->top > 0); //栈不为空

	//出栈只要栈顶top--
	//把栈顶向下移动一个单位即可实现”删除“(出栈):
	--ps->top;
}



//栈顶元素函数 -- 获取栈顶元素
//接收栈类型指针
STDataType STTop(ST* ps)
{
	//assert断言栈类型指针不为空:
	assert(ps != NULL);
	//assert断言栈为空的话就不能找栈顶元素了
	assert(ps->top > 0);

	//返回栈顶元素:
	return ps->a[ps->top - 1];
	//top即栈中元素个数:
	//top从0开始,压栈后top++,先赋值再++
	//top永远在栈顶元素的下一个位置
	//所以要获得栈顶元素就要top-1到栈顶元素位置
}



//栈中元素函数 --计算栈中元素个数
//接收栈类型指针
int STSize(ST* ps)
{
	//assert断言栈类型指针不为空:
	assert(ps != NULL);

	//top即栈中元素个数:
	//top从0开始,压栈后top++,先赋值再++
	//top永远在栈顶元素的下一个位置
	return ps->top;
}



//判空函数 -- 判断栈是否为空
//接收栈类型指针
bool STEmpty(ST* ps)
{
	//assert断言栈类型指针不为空:
	assert(ps != NULL);

	//如果top为0
	//说明栈中没有元素
	return ps->top == 0; 
	//top为0 -> 栈为空 -> 返回true
	//top不为0 -> 栈不为空 -> 返回false
}

            

            

---------------------------------------------------------------------------------------------

                

Test.c -- 栈测试文件

#define _CRT_SECURE_NO_WARNINGS 1

//包含栈头文件:
#include "Stack.h"

//测试函数:
void TestStack()
{
	//创建一个栈类型:
	ST st;
	//对其进行初始化:
	STInit(&st);
	//使用压栈往栈中增加元素:
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	STPush(&st, 5);
	//元素大于4个再次进行扩容

	//打印当前栈中元素个数:
	printf("目前栈内元素个数为:%d\n", STSize(&st));
	//换行:
	printf("\n");

	//使用while循环:
	//打印栈顶元素再出栈,循环此操作:
	//证明栈的后进先出原则
	while (!STEmpty(&st))
		//链表不为空就继续操作:
	{
		//打印当前栈顶元素:
		printf("出栈前栈顶元素:%d\n", STTop(&st));

		//进行出栈:
		STPop(&st);
	}

	//换行:
	printf("\n");
	//打印当前栈中元素个数:
	printf("目前栈内元素个数为:%d", STSize(&st));

	//进行销毁:
	STDestroy(&st);
}

//主函数
int main()
{
	TestStack();

	return 0;
}

到了这里,关于【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构初阶】二、 线性表里的顺序表

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】一. 复杂度讲解_高高的胖子的博客-CSDN博客  =======================================

    2024年02月09日
    浏览(36)
  • 数据结构入门(C语言版)线性表中链表介绍及无头单向非循环链表接口实现

    概念 : 线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素 。因此,为了表示每个数据元素与其直接后继数据元素之间的逻辑关系,对数据元素来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。这

    2023年04月09日
    浏览(48)
  • 【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】一. 复杂度讲解_高高的胖子的博客-CSDN博客  =======================================

    2024年02月08日
    浏览(44)
  • 【数据结构初阶】七、非线性表里的二叉树(堆的实现 -- C语言顺序结构)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】六、线性表中的队列(链式结构实现队列)-CSDN博客  ===========================

    2024年02月08日
    浏览(44)
  • 【数据结构初阶】四、线性表里的链表(带头+双向+循环 链表 -- C语言实现)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】三、 线性表里的链表(无头+单向+非循环链表 -- C语言实现)-CSDN博客  ====

    2024年02月08日
    浏览(45)
  • 【数据结构初阶】八、非线性表里的二叉树(二叉树的实现 -- C语言链式结构)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】七、非线性表里的二叉树(堆的实现 -- C语言顺序结构)-CSDN博客  ==========

    2024年02月08日
    浏览(51)
  • 【数据结构初阶】三、 线性表里的链表(无头+单向+非循环链表 -- C语言实现)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)-CSDN博客  =========================

    2024年02月08日
    浏览(57)
  • 用java以数组为底层数据结构创建自己的栈

    栈可以解决什么问题呢: 1.括号匹配问题 2.递归 3.表达式求值问题 首先明确栈的功能: 1.入栈:给底层数组的尾部插入元素相当于入栈 2.出栈:把底层数组的最后一个元素提出来相当于出栈 3.获取栈长度:获取size 4.判断栈是否为空:底层数组size==0则为空 5.获取栈顶:返回底层

    2024年01月20日
    浏览(43)
  • 5分钟学会数据结构中的线性链表

    除了一些算法之外,我们还要掌握一些常见的数据结构,比如 数组、链表、栈、队列、树等结构。 在之前的文章中,已经带着大家学习了Java里的一维数组和多维数组,所以对此我就不再细述了。 接下来我会给大家讲解一下线性结构中的链表,希望你能喜欢哦。 全文大约【

    2024年02月08日
    浏览(52)
  • 【数据结构】我家三岁表弟都明白的栈和队列,你不会不了解吧?

    🧑‍💻作者: @情话0.0 📝专栏:《数据结构》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢!   栈是只允许在一端进行插入或删除操作的线性表。首先栈是一种线性表,但是对其限定该线性表只能在某一端进行插入或

    2024年01月24日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包