C语言深入探究栈的原理

 更新时间:2021年11月03日 14:43:57   作者:i_Crave  
一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则

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

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

栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的 代价比较小。如下图:

下面用顺序表(数组)来实现栈;

建立一个顺序表结构:

typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top; //表示栈顶
int capacity;//表示容量,当容量满时,扩容;
}ST;

创建一个结构体变量:ST st;在传数据之前要先初始化;不然当你没赋值就直接访问时会出现乱码或者报警告;

//初始化
void StackInit(ST* ps)
{
	assert(ps);//断言,保证传进来的非空;
	ps->a = NULL;//先将顺序表指针指向空;
	ps->top = 0;//栈顶位置表示0位置;
	ps->capacity = 0;//容量为0;
}

接下来就是向栈内传数据(压栈),要传结构体地址和要传的数据;

//压栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
    //判断:数据从下标0开始,因为pot表示该插入的栈顶的位置,也是压栈的个数
    //一次插入一个数据,所以数据数量与总容量相同时,就需要扩容
	if (ps->top == ps->capacity)
	{
		//扩容,扩二倍
        //使用三目运算符判断,当是第一次扩容时,用二倍没变化,所以固定开辟4个空间;
		int retcapa = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* ret = (STDataType*)realloc(ps->a, sizeof(STDataType)*retcapa);
		if (ret != NULL)
		{
			ps->a = ret;
			ps->capacity = retcapa;
		}
		else
		{
			printf("realloc开辟失败,退出!");
			exit(-1);
		}
	}
    //扩容完,更新数据;
	ps->a[ps->top] = x;
	ps->top++;
}

有压栈就有出栈;出栈用两个接口。1.返回栈顶数据 2.出栈

因为有时候只需要访问栈顶数据不需要出栈,如果想出栈又想返回数据,就先调用1,再调用2;

//返回栈顶元素;
STDataType StackTop(ST* ps)
{
	assert(ps);
 
    //直接断言要求栈中必须要有数据;
	assert(ps->top > 0);
 
	return ps->a[ps->top - 1];
}
 
//出栈,顺序表直接把下标减一即可
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

有时候还需要返回栈中元素

//返回栈中元素个数;
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

在一些复杂结构中要直接调用查看栈中是否有数据,判断栈是否为空;

//判断栈中元素是否为空,返回布尔类型
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;//注意这里是没有数据是返回true;
}

用动态开辟的空间就必须手动释放

//释放;顺序表释放头指针即可
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

看一下如何调用的:

int main()
{
	ST st;
	StackInit(&st);
 
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 4);
	StackPush(&st, 5);
	StackPush(&st, 7);
	
    printf("%d\n",StackTop(&st));
	
    StackPop(&st);
	StackPush(&st, 8);
	
	printf("%d\n",StackTop(&st));
    StackPop(&st);
 
	StackDestroy(&st);
	return 0;
}

到此这篇关于C语言深入探究栈的原理的文章就介绍到这了,更多相关C语言 栈内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言二维数组应用之井字棋游戏

    C语言二维数组应用之井字棋游戏

    这篇文章主要为大家详细介绍了C语言二维数组应用之井字棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • opencv3/C++ 将图片转换为视频的实例

    opencv3/C++ 将图片转换为视频的实例

    今天小编就为大家分享一篇opencv3/C++ 将图片转换为视频的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • C++ 逗号运算符的具体使用

    C++ 逗号运算符的具体使用

    本文主要介绍了C++ 逗号运算符的具体使用,使用逗号运算符是为了把几个表达式放在一起,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • C语言数据结构之扩展字符详解

    C语言数据结构之扩展字符详解

    掌握C语言数据结构的关键在于理解其核心概念,扩展字符作为其中的重要一环,对于编程人员来说至关重要,本指南将为您深入剖析扩展字符的相关知识,带您轻松掌握C语言数据结构,让我们一起探索这个令人着迷的领域吧!
    2024-03-03
  • 浅谈C++中virtual的三种用法

    浅谈C++中virtual的三种用法

    这篇文章主要介绍了浅谈C++中virtual的三种用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • C++实现推箱子功能附加回撤示例

    C++实现推箱子功能附加回撤示例

    本文主要介绍了C++实现推箱子功能附加回撤示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • OpenCV实现Sobel边缘检测的示例

    OpenCV实现Sobel边缘检测的示例

    本文主要介绍了OpenCV实现Sobel边缘检测的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • C语言将数组中元素的数排序输出的相关问题解决

    C语言将数组中元素的数排序输出的相关问题解决

    这篇文章主要介绍了C语言将数组中元素的数排序输出的相关问题解决,文中的题目是将元素连接起来排成一个数并要求出这类结果中数最小的一个,需要的朋友可以参考下
    2016-03-03
  • Linux管道揭秘之匿名管道连接进程世界的方法

    Linux管道揭秘之匿名管道连接进程世界的方法

    文章介绍了Linux中的管道(Pipe)概念,包括其定义、作用、类型、工作原理以及如何在父子进程间使用,匿名管道是进程间通信的一种机制,通过pipe()系统调用创建,具有读端和写端文件描述符,文章详细解释了匿名管道的创建、使用流程、4种情况和5种特性
    2024-11-11
  • C语言绘制三角函数曲线

    C语言绘制三角函数曲线

    这篇文章主要为大家详细介绍了C语言绘制三角函数曲线,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06

最新评论