数据结构---栈的概念及顺序栈入栈、出栈等操作的实现(C语言)


本文中所涉及的完整代码及测试代码等已提交至gitee,可以点击此链接查看参考。
因为本人是编程初学者,文中及代码中难免出现错误,请同志们批评指正!
在这里插入图片描述


🎄栈的基本概念

image.png
上图是一个羽毛球筒,它只有一端开口,羽毛球在其中挨个存放,如果我们想往里面放入一只羽毛球,只能从开口处放进去,而不能随意插入。如果我们想拿出一只羽毛球,也只能从开口拿到最靠近开口的那一个,而不能越过第一个去随便拿中间的。其实这就是对栈这种数据结构的一个形象描述。

我们先对栈下一个结论:栈(stack)是仅允许在表尾进行插入和删除操作的线性表。
我们把允许插入和删除的一端称为栈顶(top), 另一端称为栈底(bottom), 不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。

对于栈的定义如何理解呢?
首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表而已。定义中说是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底。
它的特殊之处就在于限制了这个线性表的插入和删除位置,它始终只在栈顶进行。这也就使得栈底是固定的,最先进栈的只能在栈底。
栈的插入操作,叫作进栈,也称压栈、入栈。
栈的删除操作,叫作出栈,也有的叫作弹栈。

对于栈来讲,理论上线性表的操作特性它都具备,但是因为其结构的特殊性,所以插入删除这两个操作会与线性表有不同。但它到底还是一个线性表,因此根据存储结构,栈也分为顺序栈和链式栈,它们的基本思路和我们之前说的线性表和链表是几乎一样的。下面我们来看看顺序栈和链式栈的实现。


🎄顺序栈及其操作的实现

image.png

顺序表是用类似于数组的结构来实现的,顺序栈的实现也应该如此。观察上图,就是一个顺序栈的模型。
因为顺序栈中我们的栈的大小是动态的,所存储的元素个数也是动态的,因此我们需要一个变量top来代表栈顶,元素入栈则top+1,一个元素出栈则top-1。由此可以对比顺序表的结构定义初步构想出栈的结构定义:

typedef int data_t;

typedef struct
{
   
	data_t* data;//栈内数据
	int top;//栈顶位置下标,栈顶指针
	int cap;//栈中能容纳元素数量
}sqstack, * pstack;

与其他数据结构相同,我们需要实现以下操作:

  1. 顺序栈的初始化;
  2. 顺序栈入栈操作;
  3. 顺序栈出栈操作;
  4. 判断顺序栈是否空;
  5. 判断顺序栈是否满;
  6. 遍历打印顺序栈中元素;
  7. 清空顺序栈中元素;
  8. 计算顺序栈元素个数;
  9. 动态内存释放;

⭐1.顺序栈的初始化

对于顺序栈的创建与初始化,我们需要考虑使用malloc来申请动态内存空间来存放我们的栈及栈中数据。因此应该需要两次malloc:

  1. malloc申请动态内存空间来管理维护栈结构;
  2. malloc申请动态内存空间来管理维护栈中数据;
  3. 对申请的空间中的内容进行初始化:数据置空、top置-1、cap置初始值。

为了实现空间的有效利用,这里在为栈的数据申请空间的时候,应该由用户来指定这个栈中能存放多少个data_t类型的数据,即cap得值由用户指定,用多少就申请多少的空间。
top为什么要置为-1呢?因为top是栈顶指针,是栈顶元素得下标,如果栈中有一个元素,那应该是在下标为0的位置。没有元素,那top自然要置为-1。

//1. 顺序栈的初始化;
/*
* @return      init success:栈指针   init failed:NULL
* @para        maxlen:栈内元素最大数量由用户指定
*/
pstack sqstack_init(int maxlen)
{
   
	//1.给栈申请动态内存
	pstack s = (pstack)malloc(sizeof(sqstack));
	if (s == NULL)
	{
   
		printf("\nstack init failed\n");
		return NULL;
	}

	//2.给栈中的数据data申请动态内存:
	s->data = (data_t*)malloc(maxlen * sizeof(data_t)
  • 10
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值