数据结构-如何巧妙实现一个栈?逐步解析与代码示例

这篇具有很好参考价值的文章主要介绍了数据结构-如何巧妙实现一个栈?逐步解析与代码示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

栈是一种基本但强大的数据结构,它在许多算法和系统功能中扮演着关键角色。在这篇文章中,我们将深入探讨如何在实现一个栈,从基本概念到具体的代码实现,再到实际应用场景的探讨。

1.栈的基本概念

在深入代码之前,先简单介绍栈的概念。栈是一个项的有序集合,其中添加(推入)和删除(弹出)项总发生在同一端,称为“栈顶”。他是后进先出的,就好像弹夹里面的子弹一样

数据结构-如何巧妙实现一个栈?逐步解析与代码示例,数据结构,数据结构,链表

2.选择数组还是链表?

数组的优点在于实现简单,访问时间快。但其缺点是大小固定,可能会有空间浪费或不足的问题。
链表的优点在于可以动态调整大小,内存利用率高。但其缺点是相对于数组,访问时间可能会稍慢。
我们用数组来实现
数据结构-如何巧妙实现一个栈?逐步解析与代码示例,数据结构,数据结构,链表


3. 定义栈结构

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>

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

接口

void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst,STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);

4.初始化栈

初始化是栈实现中的第一步。我们需要将栈顶 top 的初始值设为0,以表示栈为空,在这个实现中,栈被定义为包含动态数组、栈顶指针和容量的结构体。初始化函数 STInit 负责设置这些属性的初始状态。

// 初始化栈
void STInit(ST* pst)
{
  assert(pst);
  pst->a = NULL;       // 初始时,数组指针为空
  pst->top = 0;        // 栈顶指针初始为0,表示栈为空
  pst->capacity = 0;   // 初始容量为0
}

5.压栈操作

在实现压栈操作时,我们要考虑栈可能满的情况。如果栈已满,我们应该阻止进一步的压栈并给出适当的反馈。

// 检查并扩展栈的容量
void SLCheckCapacity(ST* pst)
{
  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 == NULL)
    {
      perror("realloc fail");
      exit(1); // 如果内存分配失败,则退出程序
    }

    pst->a = tmp;
    pst->capacity = newCapacity;
  }
}

// 向栈中推入一个元素
void STPush(ST* pst, STDataType x)
{
  assert(pst);
  SLCheckCapacity(pst); // 检查并扩展容量
  pst->a[pst->top] = x; // 存放元素
  pst->top++;           // 栈顶指针增加
}

6.弹栈操作

弹栈时,我们需要确保栈不为空。如果尝试从空栈中弹出元素,应该返回一个错误指示。

// 从栈中弹出一个元素
void STPop(ST* pst)
{
  assert(pst);
  assert(pst->top > 0); // 确保栈不为空
  pst->top--;           // 栈顶指针减少
}

7.查看栈顶和判断栈空

这些操作相对简单,但它们对于栈的有效使用至关重要。

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

// 检查栈是否为空
bool STEmpty(ST* pst)
{
  assert(pst);
  return pst->top == 0; // 如果栈顶指针为0,则栈为空
}

9.销毁栈操作

在这个静态数组实现中,destroy 函数不是必须的,但是我们使用了动态分配的内存,则需要在此释放内存。

// 销毁栈
void STDestroy(ST* pst)
{
  assert(pst);
  free(pst->a);        // 释放栈内部的数组空间
  pst->a = NULL;       // 将数组指针置为空
  pst->top = 0;        // 栈顶指针重置为0
  pst->capacity = 0;   // 容量重置为0
}

10.测试并且打印栈内容

int main()
{
  ST stack;            // 定义栈变量
  ST* pst = &stack;    // pst 指向 stack
  STInit(pst);         // 初始化栈

  // 向栈中添加元素
  STPush(pst, 1);
  STPush(pst, 2);
  STPush(pst, 3);
  STPush(pst, 4);

  // 打印并弹出栈中的元素
  while (!STEmpty(pst))
  {
    printf("%d ", STTop(pst));
    STPop(pst);
  }
  printf("\n");

  STDestroy(pst); // 销毁栈
  return 0;
}

运行结果如下:
数据结构-如何巧妙实现一个栈?逐步解析与代码示例,数据结构,数据结构,链表


栈的实际应用

栈在计算机科学中有着广泛的应用。从函数调用的内存管理到算法中的临时数据存储,栈的应用无处不在。理解栈如何在这些场景中工作,对于充分利用其潜力至关重要。


结论

栈不仅是一种基本的数据结构,而且是理解更复杂系统和算法的基石。通过在c语言中实现和应用栈,我们不仅能够加深对这一结构的理解,还能够提高我们的编程技巧和问题解决能力。我希望这篇文章能够帮助你更好地理解和实现栈。如果你有任何问题或想分享你的经验,请在评论区留言。文章来源地址https://www.toymoban.com/news/detail-766215.html

到了这里,关于数据结构-如何巧妙实现一个栈?逐步解析与代码示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java 数据结构】实现一个二叉搜索树

    目录   1、认识二叉搜索树 2、实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法  2.4 remove 方法(重点) 3、二叉搜索树总结 从字面上来看,它只比二叉树多了搜索两个字,我们回想一下,如果要是在二叉树中查找一个元素的话,需要遍历这棵树,效率很慢,而二叉搜

    2024年02月02日
    浏览(41)
  • 【设计并实现一个满足 LRU (最近最少使用) 缓存约束的数据结构】

    LRU是Least Recently Used的缩写,意为最近最少使用。它是一种缓存淘汰策略,用于在缓存满时确定要被替换的数据块。LRU算法认为,最近被访问的数据在将来被访问的概率更高,因此它会优先淘汰最近最少被使用的数据块,以给新的数据块腾出空间。 如图所示: 先来3个元素进入

    2024年01月24日
    浏览(46)
  • 【设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构】

    LRU是Least Recently Used的缩写,意为最近最少使用。它是一种缓存淘汰策略,用于在缓存满时确定要被替换的数据块。LRU算法认为,最近被访问的数据在将来被访问的概率更高,因此它会优先淘汰最近最少被使用的数据块,以给新的数据块腾出空间。 如图所示: 先来3个元素进入

    2024年01月21日
    浏览(57)
  • 头歌(C语言)-数据结构与算法-栈的实现-第1关:实现一个顺序存储的栈

    任务描述 相关知识 栈的基本概念 栈结构的定义(C) 顺序栈的操作 编程要求 测试说明 任务描述 本关任务是实现 step1/SeqStack.cpp 中的 SS_IsFull 、 SS_IsEmpty 、 SS_Length 、 SS_Push 和 SS_Pop 五个操作函数,以实现判断栈是否为满、是否为空、求栈元素个数、进栈和出栈等功能。 相关

    2024年02月07日
    浏览(65)
  • 【数据结构】二叉树——堆如何实现

    目录 一、二叉树的顺序结构 二、堆的概念及结构 三、堆的实现 四、堆的应用 4.1 堆排序 4.1.1 建堆 4.1.2 利用堆删除思想来进行排序 4.2 TOP-K问题 很多时候,我们竞争对手是我们自己,而不是别人。   普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费

    2024年02月13日
    浏览(35)
  • 头歌(C语言)-数据结构与算法-队列-第1关:实现一个顺序存储的队列

    任务描述 相关知识 顺序存储的队列 顺序队列的主要操作 编程要求 测试说明 任务描述 本关任务:实现 step1/SeqQueue.cpp 中的 SQ_IsEmpty 、 SQ_IsFull 、 SQ_Length 、 SQ_In 和 SQ_Out 五个操作函数,以实现判断队列是否为空、是否为满、求队列长度、队列元素入队和出队等功能。 相关知

    2024年02月06日
    浏览(162)
  • 用栈的思想实现将一个十进制数字转换为八进制--数据结构

    魔王的介绍:😶‍🌫️一名双非本科大一小白。 魔王的目标:🤯努力赶上周围卷王的脚步。 魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥 ❤️‍🔥大魔王与你分享:“并不是你喝了一瓶雪花,就有人愿意陪你勇闯天涯。” 学完栈的思想后,我们知道了栈只能从栈顶进出,如果

    2023年04月24日
    浏览(44)
  • 追梦之旅【数据结构篇】——详解小白如何使用C语言实现堆数据结构

        😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主! 😘博主小留言:哈喽! 😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不

    2023年04月17日
    浏览(47)
  • [C语言实现]数据结构——手撕顺序栈之我出生就会写一个栈

    🥰作者: FlashRider 🌏专栏: 数据结构 目录 栈的前置知识 1.什么是栈? 2.生活中哪些地方有栈的影子? 顺序表实现栈 1.为什么通常采用顺序表实现栈? 2.栈的实现 栈( stack )又名堆栈,它是一种 运算受限的线性表 。限定仅在表尾进行插入和删除操作的线性表。这一端被称为

    2024年02月08日
    浏览(44)
  • 【Java】树结构SQL数据的如何去实现搜索

    错误的返回格式 错误的返回格式实现的效果 正确的返回格式 正确的展示画面 1. 根据搜索条件,查出符合的数据 这一步不能直接返回给前端的,因为前端的组件是需要完整的一个树结构。 从图中可以看到,我们 id in(70,71,72) 的父节点 id = 17 没有找到,所以 这就不是一个完整

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包