服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言 栈与数组的实现详解

C语言 栈与数组的实现详解

2022-11-09 14:58m0_52012656 C/C++

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,

的实现

首先我们思考一个问题,什么是栈?

栈是数据结构的一种,栈在我们日常编码中遇到的非常多,很多人对栈的接触可能仅仅局限在 递归使用的是栈 和 StackOverflowException,栈是一种后进先出的数据结构(可以想象生化金字塔的牢房和生化角斗场的狗洞)。

C语言 栈与数组的实现详解

栈的定义

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素

栈的应用广泛,比如你的程序执行查看调用堆栈、计算机四则加减运算、算法的非递归形式、括号匹配问题等等。所以栈也是必须掌握的一门数据结构。最简单大家都经历过,你拿一本书上下叠在一起,就是一个后进先出的过程,你可以把它看成一个栈。下面我们介绍数组实现的栈两种形式。

 

数组实现

静态栈

一般不推荐使用这种方法,因为当空间不够用时,增容会有点麻烦,不实用。

typedef struct Stack
{ 
  STDataType _a[];  //STDataType 为int宏定义,当然你也可以将它定义为其他类型,宏定义是为了换栈类型的时候方便一点
  int _top; // 栈顶
  int _capacity; // 容量
}Stack;

动态栈

相比静态栈,动态栈空间不够时可以直接时用realloc动态扩容,但是动态扩会有一定程度的消耗,我们会直接扩容一倍,当使用不完时会造成一定程度的空间浪费。

typedef struct Stack
{ 
  STDataType* _a;//指向一块开辟出来的连续空间的指针
  int _top; // 栈顶
  int _capacity; // 容量
}Stack;

栈要实现的操作

// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);

栈的初始化

void StackInit(Stack* ps)
{
  ps->_a = NULL; //初始化时将指针指向空,此时没有开辟空间
  //这里可以将top赋值为0,也可以赋值为-1。
  ps->_top = -1;  //赋值为0时表示top为栈顶元素的下一个位置的下标,赋值为-1时top为栈顶元素的下标
  ps->_capacity = 0; //栈的容量
}

入栈

C语言 栈与数组的实现详解

void StackPush(Stack* ps, STDataType data)
{
  assert(ps);
  //考虑要不要增容
  //当top为0时判断条件为
  //if(ps->top==ps->_capacity)
  if (ps->_top+1 == ps->_capacity)//当栈满时进入
  {
      //判断当前栈的容量是否为0,为0的话开辟4个空间,不为0时扩容一倍
      int newcapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
      STDataType* tmp = realloc(ps->_a, sizeof(STDataType) * newcapacity);
      if (tmp == NULL)
      {
          exit(-1);
      }
      ps->_a = tmp;
      ps->_capacity = newcapacity;
  }
  //扩容完成,或者不用扩容,开始插入
  ps->_top++;
  ps->_a[ps->_top] = data;
  //当top为0时插入操作
  //ps->_a[ps->_top] = data;
  //ps->_top++;
}

出栈

C语言 栈与数组的实现详解

void StackPop(Stack* ps)
{
  assert(ps);
  //判断是否为空
  assert(!StackEmpty(ps));//暴力判断
  //if (top==-1)//温柔判断
  //{
  //  printf("栈已经空了!\n");
  //  exit(-1); //甩出异常
  //}
  ps->_top--;
}

取栈顶元素

STDataType StackTop(Stack* ps)
{
  assert(ps);
  //判断是否为空,为空甩出异常。
  assert(!StackEmpty(ps));
  //if (!StackEmpty(ps)) {
  //  printf("栈为空!\n");
  //  exit(-1);
  //}
  return ps->_a[ps->_top]; //返回栈顶元素
}

判断栈中有几个有效数据

//取出栈里有效元素个数。
int StackSize(Stack* ps)
{
  assert(ps);
  return ps->_top+1; 
}

判断栈是否为空

bool StackEmpty(Stack* ps)
{
  assert(ps);
  return ps->_top == -1;  //ps->_top为-1返回true,否则返回false.
​
}

销毁栈

销毁栈是必不可少的的一步,如果没有销毁的话会造成内存泄露

void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_top = -1;
ps->_capacity = 0;
}

链栈

最后介绍一下链栈,这里就不实现了有兴趣的话可以自己实现一下。

链栈和链表一样的,也是通指针将各个数据块链接起来的

设计链栈是最好设计为双向链表,否则当你设计为用尾作栈顶是出栈效率低。

用头做栈顶时,头插头删,可以设计为单链表。

到此这篇关于C语言 栈与数组的实现详解的文章就介绍到这了,更多相关C语言 栈与数组内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/m0_52012656/article/details/121044862

延伸 · 阅读

精彩推荐
  • C/C++EasyC++,C++中的自增与自减

    EasyC++,C++中的自增与自减

    自增与自减是C++当中两个使用频率非常高的运算符,不仅在循环当中用到,在日常的代码当中也经常使用。...

    Coder梁5402021-11-01
  • C/C++C语言kmp算法简单示例和实现原理探究

    C语言kmp算法简单示例和实现原理探究

    这篇文章主要介绍了C语言kmp算法简单示例和实现原理探究,本文用简洁的语言说明KMP算法的原理,并给出了示例,需要的朋友可以参考下...

    C语言程序设计6992021-02-03
  • C/C++七夕表白! C语言实现爱情红玫瑰

    七夕表白! C语言实现爱情红玫瑰

    这篇文章主要为大家详细介绍了C语言实现爱情红玫瑰,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Yan_Less9132021-09-24
  • C/C++C、C++线性表基本操作的详细介绍

    C、C++线性表基本操作的详细介绍

    这篇文章主要给大家介绍了关于C、C++线性表基本操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    zhen-yu9612021-10-03
  • C/C++使用c++实现异或加密的代码示例

    使用c++实现异或加密的代码示例

    这篇文章主要为大家介绍了c++实现异或加密的代码示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪...

    羽夏10422022-11-07
  • C/C++linux中查询dns示例

    linux中查询dns示例

    这篇文章主要介绍了linux中查询dns示例,需要的朋友可以参考下...

    C语言程序设计6722021-01-19
  • C/C++VS2022实现VC++打包生成安装文件图文详细历程

    VS2022实现VC++打包生成安装文件图文详细历程

    本文主要介绍了VS2022实现VC++打包生成安装文件图文详细历程,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    cjmsea9322022-09-14
  • C/C++简单说说STL的内存管理

    简单说说STL的内存管理

    将其描述为空间配置器,理由是allocator可以将其它存储介质(例如硬盘)做为stl 容器的存储空间。由于内存是allocator管理的主要部分,因此,...

    C语言教程网12712020-12-28