栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端为栈顶,另一端为栈底。栈中元素遵循先进后出的原则
假设我们依次将1, 2, 3, 4压入栈中



当我们再全部出栈时,就从1,2,3,4变成了4,3,2,1

这就是栈的先进后出的规则,知晓了原理,下一步就开始实现。
这里我们结合栈的特性,选用顺序表来实现更优一些,而下期的队列则用链表实现

数据结构
typedef struct Stack
{DataType* data;int top;        // 栈顶int capacity;  // 容量
}Stack;
实现的接口
// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, DataType data);
// 出栈
void StackPop(Stack* ps);// 获取栈顶元素
DataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零(1),如果不为空返回0
int StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
//确认是否需要扩容
void ChackCapacity(Stack* ps);

初始化栈

void StackInit(Stack* ps)
{ps->data = (DataType*)malloc(STACKSIZE * sizeof(DataType));ps->top = 0;ps->capacity = STACKSIZE;
}

检查栈是否扩容

void ChackCapacity(Stack * ps)
{if (ps->top >= ps->capacity){ps->capacity *= 2;ps->data = (DataType*)realloc(ps->data, ps->capacity * sizeof(DataType));}
}

我们只需要判断栈顶是否超过当前容量,超过后重新分配给多空间即可

入栈

void StackPush(Stack* ps, DataType data)
{ChackCapacity(ps);ps->data[ps->top++] = data;
}

每次将数据放在栈顶的位置,再将栈顶往后推

出栈

void StackPop(Stack* ps)
{if (0 == ps->top)return;ps->top--;
}

出栈只需要把栈顶指针回退一格即可,这样我们就不能通过栈顶来访问出栈的位置

获取栈顶元素

DataType StackTop(Stack* ps)
{if (0 == ps->top)return (DataType)0;return ps->data[ps->top - 1];
}

因为我们的栈顶时刻处于栈顶元素的后一个,所以只需要返回栈顶的前一个位置即可

获取栈中有效元素个数

int StackSize(Stack* ps)
{return ps->top;
}

直接返回栈顶的位置

检测栈是否为空

int StackEmpty(Stack* ps)
{return ps->top == 0;
}

当栈顶处于栈底的位置时,说明栈为空

销毁栈

void StackDestroy(Stack* ps)
{free(ps->data);ps->data = NULL;ps->top = 0;ps->capacity = 0;
}

完整代码
头文件

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
#define STACKSIZE 10
typedef int DataType;
typedef struct Stack
{DataType* data;int top;        // 栈顶int capacity;  // 容量
}Stack;// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, DataType data);
// 出栈
void StackPop(Stack* ps);// 获取栈顶元素
DataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零(1),如果不为空返回0
int StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
//确认是否需要扩容
void ChackCapacity(Stack* ps);

函数实现

#include"Stack.h"void ChackCapacity(Stack* ps)
{if (ps->top >= ps->capacity){ps->capacity *= 2;ps->data = (DataType*)realloc(ps->data, ps->capacity * sizeof(DataType));}
}
void StackInit(Stack* ps)
{ps->data = (DataType*)malloc(STACKSIZE * sizeof(DataType));ps->top = 0;ps->capacity = STACKSIZE;
}// 入栈
void StackPush(Stack* ps, DataType data)
{ChackCapacity(ps);ps->data[ps->top++] = data;
}// 出栈
void StackPop(Stack* ps)
{if (0 == ps->top)return;ps->top--;
}// 获取栈顶元素
DataType StackTop(Stack* ps)
{if (0 == ps->top)return (DataType)0;return ps->data[ps->top - 1];
}// 获取栈中有效元素个数
int StackSize(Stack* ps)
{return ps->top;
}// 检测栈是否为空,如果为空返回非零(1),如果不为空返回0
int StackEmpty(Stack* ps)
{return ps->top == 0;
}// 销毁栈
void StackDestroy(Stack* ps)
{free(ps->data);ps->data = NULL;ps->top = 0;ps->capacity = 0;
}

数据结构与算法 | 栈相关推荐

  1. 数据结构与算法-栈与队列

    数据结构与算法-栈与队列 栈 基本概念 简单表述就是仅在表尾进行插入和删除操作的线性表. 常见操作 入栈和出栈, 均在线性表的尾部进行. 基本原则就是, 先入后出. 队列 基本概念 和栈不同的是,队列 ...

  2. 数据结构与算法 -- 栈 ADT

    这两天翻了下数据结构与算法分析.严蔚敏的数据结构.C和指针.C Primer Plus这些本书,受益很多.不过大多的示例不够完整,需要自己动手编写程序.又看了遍培训时的笔记,虽然很糙但是精华的部分还是 ...

  3. 数据结构与算法 / 栈(stack)

    @time 2019-07-24 @author Ruo_Xiao @reference 极客时间 -> 数据结构与算法之美 ---------------------------------- ...

  4. JavaScript数据结构与算法——栈详解

    1.栈基本知识 栈是一种特殊的列表,栈的元素只能通过列表的一端访问,这一端成为栈顶,栈具有先进后出的特点,要想访问栈底的元素,就必须将上边的元素先拿出来.对栈的操作主要是入栈和出栈,通过push()和 ...

  5. 数据结构与算法 栈的数组实现

    Java数据结构和算法 上一篇 主目录 下一篇 package stack;import java.util.Scanner;public class ArrayStackDemo {public s ...

  6. 1. 数据结构与算法——栈

    数据结构与算法 数据结构是计算机中存储.组织数据的方式 算法通俗理解就是解决问题的方法/步骤逻辑 定义:1.一个有限的指令集,每条指令的描述不依赖与语言2.接受一些输入(也可能不需要输入),产生输出3 ...

  7. char栈java,Java数据结构与算法-栈和队列(示例代码)

    (摘录加总结)------ 栈和队列不属于基础的数据结构,它们都属于线性表. 一.栈 对于栈存储操作元素只能在栈结构的一端进行元素的插入和删除,是一种性质上的线性表结构.按照"先进后出&qu ...

  8. 数据结构与算法—栈详解

    目录 什么是栈 设计与介绍 数组实现 结构设计 push插入 pop弹出并返回首位 其他操作 链表实现 结构设计 push插入 pop弹出 其他操作 实现代码 数组实现 链表实现 测试 总结 什么是栈 ...

  9. 数据结构和算法——栈、队列、堆

    文章目录 1.预备知识 1.1 栈 1.2 队列 1.3 堆 2.用队列实现栈 2.1 题目描述 2.2 解题思路 2.3 C++实现 3.用栈实现队列 3.1 题目描述 3.2 解题思路 3.3 C ...

最新文章

  1. 【Spring源码分析系列】bean的加载
  2. 最新鲜最详细的Android SDK下载安装及配置教程
  3. 工作207:修改表头按钮样式
  4. 把一张合成图分拆出各个小图
  5. 简单的二次封装axios中的get,post方法
  6. 虚拟机安装 xp步骤(参照百度文库)
  7. 工程监测管理平台、工程数据看板、工程总览、动态模型、数据分析、数据跟踪、建筑工地、数据报表、警点管控、现场记录、观测记录、测点管理、模型管理、文档管理、墙体下沉、成员管理、axure原型、产品原型
  8. 快应用不会取代 App,未来将赋能 IoT!
  9. 和信虚拟终端的全面部署-虚拟终端网络工程实施
  10. 无法连接终端授权服务器,许可证已过期的客户端可能无法连接到终端服务器的解决方案...
  11. [ExtJS] ExtJS颜色选择器
  12. iphone11 sim卡故障_苹果手机出现sim卡故障怎么处理?
  13. 万字吐血好文,一线分析师的4大总结。
  14. 从零开始学习C语言开发视频教程在线完整版
  15. 中国过氧化二异丙苯市场投资状况分析与前景趋势研究报告2022年版
  16. 算法笔记04--分治法之寻找最大最小元素
  17. JavaScript,css时间计时器
  18. 获取现在的Unix时间戳(Unix timestamp)的方法-在线时间戳转换器
  19. Android APP切换系统语言
  20. 谷歌浏览器跨域问题解决方案

热门文章

  1. Zuul简介及代码示例
  2. Nginx_反向代理配置讲解
  3. Oracle之表分区、分区索引(一)
  4. sql参数化还是被注入了_SQL注入是什么?
  5. multiprocessing.manager管理的对象需要加锁吗_iOS内存管理布局-理论篇
  6. C++17中那些值得关注的特性
  7. 0619-dedeCMS的安装、重装、目录说明、基本操作及注意事项
  8. 以持续集成工具实现DevOps之禅
  9. CentOS 7 yum方式快速安装MongoDB
  10. 关于“无法完成该动作 到Microsoft Exchange的连接不可用”的解决办法