初识栈与队列(1)

        大家好呀,今天我们先来认识一下栈。

栈与队列

目录

栈与队列

栈 

创建栈 

初始化和销毁 

 入栈和出栈

 访问栈顶的数据

 检查栈是否为空

 计算元素个数

 检查打印

完整代码 

stack.h 

 stack.c

 test.c

小结


栈 

        我们先来认识栈。什么是栈呢?

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

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

        

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

        

        栈讲究的是先进后出的原则,也就是说,栈顶的部分的插入和删除需要较为方便。相比于链表,用数组,也就是顺序表来实现栈则更为的方便,那我们就来对栈进行实现。

创建栈 

        那么栈需要使用结构体包含成员吗?当然,栈的元素一般都不止一个,因此我们创建结构体来包含其元素。代码如下:

typedef struct Stack
{
	int* a;
	int top;      //标识栈顶位置
	int capacity; //检查容量
}ST;

         那么首要的,便是将栈进行初始化,那我们就先来编写初始化和销毁函数。

初始化和销毁 

        先编写初始化函数。

        初始化我们都很熟悉了,将指针置空,容量置0就可以了。要注意的是,栈顶位置的赋值需要进行思考,因为如果赋值为0的话,当top==0时。区分栈只有一个元素还是栈为空较为困难,所以可以选择将top的值赋值为-1。我们这里还是选择将其赋值为0。 代码如下:

void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->top = 0;
	pst->capacity = 0;
}

        接着便是销毁函数。

        销毁的话进行置空和free就可以了。代码如下:

void Destroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}
 入栈和出栈

        接下来便是让元素入栈和出栈,相当于尾插和尾删。

        入栈函数,首要的便是在入栈前检查容量是否足够,不够,则进行扩容。接下来我们来编写入栈。入栈,只需要将数组的尾部,也就是栈顶插入新的数据即可。 插入完成后将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 = realloc(pst->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("malloc fail");
			exit(-1);
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}

        那么出栈,也就是尾删,就过于简单了,直接让top--即可,当然top0时就不能减少了。需要判断。代码如下:

void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}
 访问栈顶的数据

        接下来便是访问栈顶的数据,直接进行访问即可,要注意的时,因为将top置为0,我们访问top相当于访问栈顶元素的下一个,因此访问栈顶元素需要-1。代码如下:

        

STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	return pst->a[pst->top - 1];
}
 检查栈是否为空

        检查栈是否为空也是比较简单的,我们是将top初始化为0,因此当top0的时候,栈就空了。代码如下:

bool STEmpty(ST* pst)
{
	if (pst->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}
 计算元素个数

        计算栈元素个数也较为简单,top的个数就是栈元素的个数。代码如下:

int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}
 检查打印

        当然,我们最后还是来检查一下,编写是否存在错误。我们让1,2,3,4依次入栈,访问完栈顶元素后进行出栈。代码如下:

int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);

	while (!STEmpty(&s))
	{
		printf("%d ", STTop(&s));
		STPop(&s);
	}
	printf("\n");

	return 0;
}

         运行结果如下:

        

完整代码 

stack.h 
#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;

//初始化
void STInit(ST* pst);

//销毁
void Destroy(ST* pst);

//入栈
void STPush(ST* pst, STDataType x);

//出栈
void STPop(ST* pst);

//访问栈顶数据
STDataType STTop(ST* pst);

//检查栈是否为空
bool STEmpty(ST* pst);

//元素个数
int STSize(ST* pst);
 stack.c
#include"stack.h"

//初始化
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->top = 0;
	pst->capacity = 0;
}

//入栈
void STPush(ST* pst, STDataType x)
{
	assert(pst);
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : (pst->capacity) * 2;
		STDataType* tmp = realloc(pst->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("malloc fail");
			exit(-1);
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}

//出栈
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}

//访问栈顶数据
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	return pst->a[pst->top - 1];
}

//检查栈是否为空
bool STEmpty(ST* pst)
{
	if (pst->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

//销毁
void Destroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}
 test.c
#include"stack.h"

int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);

	while (!STEmpty(&s))
	{
		printf("%d ", STTop(&s));
		STPop(&s);
	}
	printf("\n");

	return 0;
}

小结

        对栈的认识到这里就结束啦,队列也会很快端上来的,我们下次见! 

  • 33
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值