数据结构之栈

目录

一. 栈的定义与性质

二. 栈的top指针的位置的选择

 三. 代码实现

3.1 顺序栈 

3.1.1 初始化

 结构体:

3.1.2 销毁栈

3.1.3 入栈

3.1.4 出栈

3.1.5 判空 

测试用例

运行结果

完整代码


一. 栈的定义与性质

顺序栈是一种后进先出(LIFO)的数据结构,通过动态数组实现,支持动态扩容和收缩。主要操作包括入栈、出栈、获取栈顶元素和判断栈空,适用于需要快速访问最后存入数据的场合。

二. 栈的top指针的位置的选择

方案一:选择top指向栈顶元素的当前位置,那么top指针就只能选择初始化在-1的位置。

方案二:如果选择top指针为栈顶元素的下一个位置,那么top指针初始化为0.

 三. 代码实现

3.1 顺序栈 

3.1.1 初始化

void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;
}
 结构体:
typedef int STDataType;
typedef struct Stack
{
	int* a;
	int top;		//标识栈顶的位置data下标
	int capacity;
}ST;

如果不懂 int* p,与int *p的区别的小伙伴请移步我的这一篇博客。

C语言,数据结构指针,结构构体操作符 •,->,*的区别,看这篇就够了_*指针->和指针->的区别-CSDN博客

3.1.2 销毁栈

void STDestory(ST* pst)
{
	assert(pst);
	free(pst->a);
}

3.1.3 入栈

入栈之前要先判断是否空间不够即是否栈满,其次在动态扩容之前要先判断是否容量初始化为0,如果初始化为0那么在就要赋初值为4,否则就直接扩二倍

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

3.1.4 出栈

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

3.1.5 判空 

bool STEmpty(ST* pst)
{
	if (pst->top == 0)
		return false;
	else
		return true;
}

测试用例

#define _CRT_SECURE_NO_WARNINGS
#include"stack.h"

int test()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	printf("%d ",STTop(&st));
	STPop(&st);
	printf("%d ", STSize(&st));
	printf("%d ", STTop(&st));
}
int main()
{
	test();
	return 0;
}

运行结果

完整代码

//stack.h 文件
#pragma once
// 防止头文件重复包含

#include<stdio.h>
// 引入标准输入输出库

#include<stdlib.h>
// 引入标准库,用于内存分配和释放

#include<stdbool.h>
// 引入标准布尔库,以使用布尔类型

#include<assert.h>
// 引入断言库,用于进行条件检测

typedef int STDataType;
// 定义栈中存储元素的数据类型为整数

typedef struct Stack
{
    int* a;          // 指向栈的动态数组
    int top;         // 标识栈顶的位置(即栈中下一个空位的索引)
    int capacity;    // 栈的当前最大容量
} ST;
// 定义栈的结构体

void STInit(ST* pst);
void STDestory(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 文件
#define _CRT_SECURE_NO_WARNINGS
// 定义一个宏,用于在Visual Studio环境下禁止某些安全警告

#include "stack.h"
// 包含栈的头文件,通常用于分离声明和实现

// 初始化栈
void STInit(ST* pst)
{
    assert(pst);        // 断言,确保pst指针非空
    pst->a = NULL;      // 初始化动态数组指针为NULL
    pst->capacity = 0;  // 初始化容量为0
    pst->top = 0;       // 初始化栈顶索引为0
}

// 销毁栈
void STDestory(ST* pst)
{
    assert(pst);        // 断言,确保pst指针非空
    free(pst->a);       // 释放动态数组占用的内存
}

// 向栈中插入元素
void STPush(ST* pst, STDataType x)
{
    assert(pst);         // 断言,确保pst指针非空
    // 扩容
    if (pst->top == pst->capacity)  // 如果栈已满
    {
        int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;  // 新容量是原容量的两倍,若原容量为0则设为4
        STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
        if (tmp == 0)
        {
            perror("realloc fail");  // 内存分配失败时打印错误信息
            return;
        }
        pst->a = tmp;
        pst->capacity = newcapacity;
    }
    pst->a[pst->top] = x;  // 将新元素放入栈顶
    pst->top++;            // 栈顶索引增加
}

// 从栈中弹出元素
void STPop(ST* pst)
{
    assert(pst);         // 断言,确保pst指针非空
    assert(pst->top > 0);// 断言,确保栈不为空
    pst->top--;          // 栈顶索引减1
}

// 返回栈顶元素
STDataType STTop(ST* pst)
{
    assert(pst);         // 断言,确保pst指针非空
    assert(pst->top > 0);// 断言,确保栈不为空
    return(pst->a[pst->top - 1]);  // 返回栈顶元素
}

// 判断栈是否为空
bool STEmpty(ST* pst)
{
    return pst->top == 0;  // 如果栈顶索引为0,则栈为空
}

// 返回栈的大小
int STSize(ST* pst)
{
    assert(pst

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值