数据结构:栈(Stack)

写有“售后”的博客:一定回复评论和私信,答疑解惑到底,认真探讨大家的疑问,欢迎大家多多指出批评与建议。

一、栈的简介

在这里插入图片描述

  栈就像一个一端封闭的羽毛球筒,添加/删除数据就像放入/拿出羽毛球
  栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中数据元素遵循“先入后出”(“后入先出”)原则
  压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
  出栈:栈的删除操作叫做出栈,出数据也在栈顶

二、顺序栈的基本操作

相关的头文件

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

  #pragma once防止头文件被重复包含
  <assert.h>是assert断言的头文件
  <stdlib.h>是动态内存空间开辟函数以及free释放的头文件
  <stdbool.h>是布尔类型头文件

定义顺序栈结构体

typedef int STDataType;
typedef struct Stack
{
	STDataType* a; 
	int top;        
	int capacity;  
}ST;

  栈中存放的数据可能变为各种类型,我们为了修改方便使用typedef 类型 STDataType;
  STDataType* a; 用于存放栈的各个元素,指针形式便于动态扩容
  top指向栈顶数据的下一个数据(初始指向0)/指向栈顶数据(初始指向-1)
  capacity表示栈的空间大小

栈的初始化

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

  为了让形参的改变影响实参,我们使用传址调用,实参传地址,那么我们形参用指针接收
  函数接收指针后都要判断指针是否为空,本文我们都用assert断言判断
  我们的top初始化为0,说明我们让top指向栈顶数据的下一个数据

栈的销毁

void STDestory(ST* pst)
{

	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}

检查栈是否需要动态扩容

void STCheckCapacity(ST* pst)
{
	assert(pst);
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;
		STDataType* temp = (STDataType*)realloc(pst->a,newcapacity*sizeof(STDataType));
		if (temp == NULL)
		{
			perror("realloc");
			return ;
		}
		pst->a = temp;
		pst->capacity = newcapacity;
	}
}

  top指向栈顶数据的下一个数据,相当于size表示数据个数,最开始时,栈顶数据在-1位置,top和capacity都在0位置,0个数据占据0个空间,入栈需要动态扩容。易知每当top==capacity时,都需要动态扩容
  使用三目操作符,需要动态扩容时,若capacity为0则变为4,不为零则变为二倍的capacity
  使用realloc函数改变空间大小,pst->a为NULL时,realloc相当于malloc。使用中介temp而非a直接接收realloc的返回值,防止realloc函数返回空造成原空间的丢失

入栈

void STPush(ST* pst, STDataType x)
{
	assert(pst);
	STCheckCapacity(pst);
	pst->a[pst->top] = x;
	pst ->top++;
}

  入栈需判断是否需要动态扩容
  若top初始指向-1,应该先++,再插入数据

出栈

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

  出栈需确保栈内有数据,即top大于0

获取栈顶数据

STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	return pst->a[pst->top-1];
}

  获取数据也要确保栈内有数据,即top大于0
  避雷return pst->a[ pst->top-- ];的写法,-- 是先执行后减减,相当于获取该栈顶数据的下一个数据后再删除该数据,不仅越界访问,还给我出栈了。

判断栈是否为空

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

获取数据个数

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

完。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值