数据结构第六章:栈的学习

目录

  • 一.栈的概念和结构
  • 二.栈的实现方式
  • 三.栈的头文件实现
  • 四.栈的具体函数实现
    • 1.栈区的初始化
    • 2.销毁栈区
    • 3.入栈
    • 4.出栈
    • 5.返回栈顶元素
    • 6.返回栈区大小
    • 7.判断栈区是否为空

一.栈的概念和结构

栈:一种特殊的线性表,只允许在固定的一端插入和删除元素操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底,栈中的数据元素遵循后进先出的原则。

压栈:栈的插入操作叫做进栈压栈或者入栈。

出栈区:栈的删除操作叫做出栈。

二.栈的实现方式

栈区可以用两种实现方式,一种是链表方式,另一种则是顺序表实现方式。下面来对比一下两种实现方式的优缺点。

对比维度 顺序表实现栈 链表实现栈
底层结构 连续内存空间,用数组存储,栈顶指针指向数组下标 非连续节点,每个节点包含数据域和指针域,栈顶指针指向头节点
内存管理 静态分配或动态扩容,存在内存浪费 动态分配节点,按需申请或者释放内存,没有空间浪费,但是每个节点都占有额外的指针空间。
适用场景 追求高速访问 容量不确定,频繁增删数据元素。

如果用数组实现栈结构:相当于之前讲解的顺序表头插尾插,用尾做栈顶。唯一的缺陷就是会造成空间浪费。空间不够需要赠容。

如果用链表实现栈结构:如果用尾做栈顶,需要用到双向链表。如果要用单链表的话,需要用头做栈顶。

三.栈的头文件实现

cpp 复制代码
typedef int SLDataType;//利用typedef关键字方便后续修改为存储其他数据结构的栈
typedef struct Stack
{
  SLDataType *a;//数据
  int top;//栈顶下标
  int capacity;//容量
}ST;
void StackInit(ST*ps);//初始化栈函数
void StackDestory(ST*ps);//删除栈函数
void StackPush(ST*ps,SLDataType x);//入栈
void StackPop(ST* ps);//出栈
STDataType StackTop(ST *ps);//返回栈顶节点
int StackSize(ST *ps);//返回栈区大小
bool StackEmpty(ST*ps);//判断栈是否为空栈

四.栈的具体函数实现

1.栈区的初始化

cpp 复制代码
void StackInit(ST* ps)
{
  assert(ps);
  ps->a=(STDataType *)malloc(sizeof(STDataType)*4);
  ps->capacity=4;
  ps->top=0;
}

上述代码的具体解释:首先利用assert函数防止栈区为空(初始化失败),其次利用malloc函数申请4个大小为sizeof(STDataType)的字节空间。最后更新栈结构成员的数据,将容量变为4,栈顶下标更改为0。

初始top为0,意味着top指向的是栈顶得下一个元素。

初始top为-1,意味着top指向的是栈顶元素。

2.销毁栈区

cpp 复制代码
void StackDestory(ST *ps)
{
  assert(ps);
  free(ps->a);
  ps->a=NULL;
  ps->top=ps->capacity=0;
}

上述代码的具体解释:首先释放掉指向栈数据指针,后将栈顶下标和栈容量置为0

3.入栈

cpp 复制代码
void StackPush(ST *ps,STDataType x)
{
  assert(ps);
  if(ps->top==ps->capacity)
  {
    STDataType *tmp=(STDataType *)realloc(ps->a,ps->capacity*2*sizeof(STDataType));
    if(tmp==NULL)
    {
      printf("realloc fail!");
      exit(-1);
    }
    else 
    {
      ps->a=tmp;
      ps->capacity*=2;
    }
  }
  ps->a[ps->top]=x;
  ps->top++;
}

上述代码的具体解释:首先处理 空间不足的情况,当空间不足时利用realloc函数进行申请原空间大小两倍的空间。如果申请失败,则打印失败信息。如果申请,成功则将临时申请的空间赋值给栈的数据变量。更新容量的变化,然后将需要入栈的数据插入即可。

4.出栈

cpp 复制代码
void StackPop(ST *ps)
{
  assert(ps);
  assert(ps->top>0);
  ps->top--;
}

上述代码的具体解释:因为数据类型多样性,所以直接将栈顶下标自减一即可。

5.返回栈顶元素

cpp 复制代码
STDataType StackTop(ST *ps)
{
  assert(ps);
  assert(ps->top>0);
  return ps->a[ps->top-1];
}

上述代码的具体解释:因为栈顶指针指向的是栈顶元素下一个,所以减一之后的下标便是栈顶部元素的下标,利用顺序表的特性就可以直接返回。

6.返回栈区大小

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

7.判断栈区是否为空

cpp 复制代码
bool StackEmpty(ST* ps)
{
  assert(ps);
  return ps->top==0;
}

上述代码的具体解释:如果栈顶为0,说明栈内没有元素则返回1,否则返回0。

相关推荐
垆边人似月.5 分钟前
华为题:滑动窗口最大值
数据结构·c++·算法
m0_5474866630 分钟前
《数据结构 (C语言)》期末试卷及答案(10套)2026版
c语言·开发语言·数据结构
杜 硕1 小时前
归并排序详解
数据结构·算法·排序算法
_wxd6663 小时前
二叉搜索树(BST)万字详解:概念、操作、性能分析与 C++ 实现
数据结构·c++·二叉搜索树
Logic1013 小时前
C语言/数据结构动态规划题解:字符串变回文的最少操作次数——最长回文子序列(LPS)
c语言·数据结构·算法·动态规划·时间复杂度·回文串·最长回文子序列
Logic1014 小时前
C语言/数据结构组合数学题解:数字好排列计数——质数倍数分类与阶乘取模
c语言·数据结构·算法·组合数学·时间复杂度·排列·取模运算
沫璃染墨5 小时前
《从零入门数据结构与算法(二):线性表详解——从顺序表原理到静态与动态实现》
c语言·数据结构·顺序表
爱读书的小胖5 小时前
Codewars Sum of a Sequence Hard Core Version C 解题分析
c语言·数据结构·算法
晴天的雨.9925 小时前
【C++】 priority_queue知识点总结
开发语言·数据结构·c++
闻缺陷则喜何志丹5 小时前
概要设计说明书应包括的内容
数据结构