栈和队列之栈

本文详细介绍了栈的概念,栈的LIFO原则,以及如何用链表实现栈的结构,包括初始化、销毁、入栈、出栈、获取栈顶元素、元素个数和判断栈是否为空的操作。
摘要由CSDN通过智能技术生成

1.栈

1.1栈的概念及结构

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

这样就类似于烤串一样,去穿竹签的时候,先穿进去的肉总是最后吃,而最后穿进去的肉则是先吃

1.2栈的实现

接下来我们用链表去实现栈

1.准备工作

首先还是三个文件,一个测试,一个写函数另外一个写库函数和定义

头文件

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int STDatatype;
typedef struct Stack
{
	STDatatype* a;
	int top;
	int capacity;
}ST;
//初始化
void STInit(ST* ps);
//销毁
void STDestory(ST* ps);

//栈顶
//入栈
void STPsuh(ST* ps, STDatatype x);
//出栈
void STPop(ST* ps);
//获取栈顶元素
STDatatype STTop(ST* sp);
//获取栈顶元素个数
int STSize(ST* ps);
//判断栈是否为空
bool STEmpty(ST* ps);

还是先包含我们所需要的库函数,同时将栈的模拟写出来

将int重新命名一下,然后写一个结构体,里面有指针a,栈顶数据top和容量capacity,并将栈给重命名为ST

然后是需要初始化STInit,销毁destory,入栈push,出栈pop,取栈顶数据stpop,获取栈的有效元数个数stsize以及判断栈是否为空empty

2.初始化

初始化的话我们先断言传递的ps是否为野指针,再将指针a置为空指针

将栈顶元素top和容量置为空

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

3.销毁

既然是销毁的话

我们需要断言ps

然后将ps指向的指针a给free掉

再将a置为空

并且将top和capacity置为0

void STDestory(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;

}

4.入栈

还是先断言ps

然后想一下,我们既然要将数据给推入栈中

如果空间满了怎么办?

那么需要开辟空间

新定义一个新的指针,并开辟新的空间

再将新开辟的空间赋予结构体里面的指针a

并且让数据x推入到a中,并让top+1(为了让下一个也有它的空间,而不是覆盖)

void STPsuh(ST* ps, STDatatype x)
{
	assert(ps);
	//空间满了开辟空间
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDatatype* tmp = (STDatatype*)realloc(ps->a, newcapacity * sizeof(STDatatype));
		if (tmp == NULL)
		{
			perror("reallco fall");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	

	ps->a[ps->top] = x;
	ps->top++;
}

5.出栈

出栈的话比较简单

首先是断言

其次需要断言是否为空,不为空就让top去-1

比如原来是1,2,3,4,结果我们需要出栈,这时候top--,这样就变成了1,2,3,但4并没有消失,如果我们需要再入栈一个5,那么top一加,就会让5去覆盖之前的4

void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	ps->top--;

}

6.获取栈顶元素

获取栈顶元素的话,我们需要判断是否为空

不为空我们只需要返回a中的top-1就可以

因为这里的a可以转化为数组

STDatatype STTop(ST* ps)
{
    assert(ps);
    assert(!STEmpty(ps));

    return ps->a[ps->top - 1];
}

7.获取栈顶元素个数

获取个数的话

我们只需要返回top就可以

因为之前我们在入栈中让top不断加加,从0开始加的有了第一个那么就加一,所以有几个元素个数那么top的值就对应几

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

 8.判断栈是否为空

判断为空的话只需要返回top是否为0

因为这里的top可以代表有效个数

bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值