[数据结构]栈详解

目录

一、栈的概念及其结构

二、栈的实现

[1.栈的初始化 void STInit(ST* ps);](#1.栈的初始化 void STInit(ST* ps);)

[2.栈的插入 void STPush(ST* ps, STDataType x);](#2.栈的插入 void STPush(ST* ps, STDataType x);)

[3.栈的删除 void STPop(ST* ps);](#3.栈的删除 void STPop(ST* ps);)

[4.栈的大小计算 int STSize(ST* ps);](#4.栈的大小计算 int STSize(ST* ps);)

[5.判断栈是否为空 bool STEmpty(ST* ps);](#5.判断栈是否为空 bool STEmpty(ST* ps);)

[6.栈的销毁 void STDestroy(ST* ps);](#6.栈的销毁 void STDestroy(ST* ps);)

[7.访问栈顶元素 STDataType STTop(ST* ps);](#7.访问栈顶元素 STDataType STTop(ST* ps);)

三、栈的操作合集

Stack.h

stack.c

test.c


一、栈的概念及其结构

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

二、栈的实现

栈的实现一般可以使用 数组或者链表实现 ,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

1.栈的初始化 void STInit(ST* ps);

复制代码
//栈的初始化
void STInit(ST* ps)
{
       assert(ps);
       ps->a = malloc(sizeof(STDataType) * 4);
       if (ps->a == NULL)
       {
              perror("malloc fail");
              return;
       }
       ps->capacity = 4;
       ps->top = 0;//代表top表示的是栈顶元素的下一个位置:刚开始top指向的是第一个元素,表示0,当第一个元素插入后top++表示1
}

2.栈的插入 void STPush(ST* ps, STDataType x);

复制代码
//栈的插入
void STPush(ST* ps, STDataType x)
{
       assert(ps);
       if (ps->top == ps->capacity)
       {
              STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) *  ps->capacity * 2);//扩容到当前的二倍
              if (tmp == NULL)
              {
                      perror("realloc fail");
                      return;
              }
                      ps->a = tmp;
                      ps->capacity *= 2;
       }
       ps->a[ps->top] = x;
       ps->top++;
}

3.栈的删除 void STPop(ST* ps);

复制代码
//栈的删除
void STPop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       ps->top--;
      
}

在栈操作函数中,栈指针 ps 是操作栈的基础,如果 ps 为 NULL,那么后续对 ps 指向的栈结构的任何访问(如 ps->top)都会导致未定义行为,通常是程序崩溃。因此,在进行栈操作之前,需要先确保 ps 不是 NULL,assert(!STEmpty(ps)); 实际上是在检查栈不为空的情况下才继续执行后续操作

4.栈的大小计算 int STSize(ST* ps);

复制代码
int STSize(ST* ps)
{
       assert(ps);
       return ps->top;
}

5.判断栈是否为空 bool STEmpty(ST* ps);

复制代码
//判断栈是否为空
bool STEmpty(ST* ps)
{
       assert(ps);
       return ps->top == 0;
}

6.栈的销毁 void STDestroy(ST* ps);

复制代码
//栈的销毁
void STDestroy(ST* ps)
{
       assert(ps);
       free(ps->a);
       ps->a = NULL;
       ps->top = 0;
       ps->capacity = 0;
}

7.访问栈顶元素 STDataType STTop(ST* ps);

复制代码
//访问栈顶元素
STDataType STTop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       return ps->a[ps->top-1];
}

三、栈的操作合集

Stack.h

复制代码
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#define N 10
typedef int STDataType;
typedef struct Stack
{
       int* a;
       int top;//下标
       int capacity;
}ST;
//栈的初始化
void STInit(ST* ps);
//栈的插入
void STPush(ST* ps, STDataType x);
//栈的删除
void STPop(ST* ps);
//
int STSize(ST* ps);
//判断栈是否为空
bool STEmpty(ST* ps);
//栈的销毁
void STDestroy(ST* ps);
//访问栈顶元素
STDataType STTop(ST* ps);
//不支持打印,因为不能保证后进先出

stack.c

复制代码
#include"Stack.h"
//栈的初始化
void STInit(ST* ps)
{
       assert(ps);
       ps->a = malloc(sizeof(STDataType) * 4);
       if (ps->a == NULL)
       {
              perror("malloc fail");
              return;
       }
       ps->capacity = 4;
       ps->top = 0;//代表top表示的是栈顶元素的下一个位置:刚开始top指向的是第一个元素,表示0,当第一个元素插入后top++表示1
}
//栈的插入
void STPush(ST* ps, STDataType x)
{
       assert(ps);
       if (ps->top == ps->capacity)
       {
              STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) *  ps->capacity * 2);//扩容到当前的二倍
              if (tmp == NULL)
              {
                      perror("realloc fail");
                      return;
              }
                      ps->a = tmp;
                      ps->capacity *= 2;
       }
       ps->a[ps->top] = x;
       ps->top++;
}
//栈的删除
void STPop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       ps->top--;
       /*在栈操作函数中,栈指针 ps 是操作栈的基础,如果 ps 为 NULL,
              那么后续对 ps 指向的栈结构的任何访问(如 ps->top)都会导致未定义行为,
              通常是程序崩溃。因此,在进行栈操作之前,需要先确保 ps 不是 NULL
              assert(!STEmpty(ps)); 实际上是在检查栈不为空的情况下才继续执行后续操作*/
}
//
int STSize(ST* ps)
{
       assert(ps);
       return ps->top;
}
//判断栈是否为空
bool STEmpty(ST* ps)
{
       assert(ps);
       return ps->top == 0;
}
//栈的销毁
void STDestroy(ST* ps)
{
       assert(ps);
       free(ps->a);
       ps->a = NULL;
       ps->top = 0;
       ps->capacity = 0;
}
//访问栈顶元素
STDataType STTop(ST* ps)
{
       assert(ps);
       assert(!STEmpty(ps));
       return ps->a[ps->top-1];
}

test.c

复制代码
#include"Stack.h"
int main()
{
       ST st;
       STInit(&st);
       STPush(&st, 1);
       STPush(&st, 2);
       STPush(&st, 3);
       STPush(&st, 4);
       STPush(&st, 5);
       while (!STEmpty(&st))
       {
              printf("%d ", STTop(&st));
              STPop(&st);
       }
       STDestroy(&st);
}
相关推荐
qqxhb41 分钟前
零基础数据结构与算法——第四章:基础算法-排序(中)
数据结构·算法·排序算法·归并·快排·堆排
木叶丸2 小时前
编程开发中,那些你必须掌握的基本概念
前端·数据结构·编程语言
手握风云-3 小时前
优选算法的链脉之韵:链表专题
数据结构·算法·链表
老虎06275 小时前
数据结构(Java)--位运算
java·开发语言·数据结构
小汉堡编程8 小时前
数据结构——vector数组c++(超详细)
数据结构·c++
雾里看山11 小时前
顺序表VS单链表VS带头双向循环链表
数据结构·链表
好好研究14 小时前
学习栈和队列的插入和删除操作
数据结构·学习
挺菜的17 小时前
【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
java·数据结构·算法
2401_8582861117 小时前
125.【C语言】数据结构之归并排序递归解法
c语言·开发语言·数据结构·算法·排序算法·归并排序
双叶83618 小时前
(C++)学生管理系统(正式版)(map数组的应用)(string应用)(引用)(文件储存的应用)(C++教学)(C++项目)
c语言·开发语言·数据结构·c++