当前位置: 首页 > news >正文

c语言数据结构与算法--简单实现栈和队列的出栈与入栈

(一)栈的基本概念

栈(Stack)是限定仅在表尾进行插入和删除操作的线性表,如铁路调度。如下 图:

(二)栈的的表现形式

栈有两种表示形式:栈的表示和实现、栈的 链式表示。

1.栈的表示和实现

利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。如下图:

同时设置栈顶指针(top)和栈底指针(base)。当 top = base 表示栈空;增加一 个元素,top 增加 1;删除栈顶元素,top  1。非空栈顶指针始终在始终在栈顶元素 的下一个位置。

2.栈的链式表示

当栈的长度无法估计时最好用栈的链式表示,如下图所示。

结点包含数据元素和指针两个数据域。

(三)栈的链式表示时元素压入、弹出 算法实现思路

1.栈的线性链表的压入算法

压入算法过程为:定义新的结点 p、修改新结 点的指针(指向原栈顶结点 top)、给新结点 p  值为 x、修改新栈顶的指针(指向新结点 p)。

2.栈的线性链表的弹出算法

弹出算法过程为:将栈顶结点 top 赋给 p、取结点 p 的值并赋给 x、调整栈顶位置(指向结点 p 的下一个结点)、释放结点 p 的空间。

(四)算法的实现

栈的顺序存储代码表示(已给出具体代码的注释):

#define _CRT_SECURE_NO_WARNINGS  
#include <stdio.h>  
#include <stdlib.h>  // 定义栈结构体
typedef struct {int data[100];  // 存储栈数据的数组int top;        // 栈顶指针int bottom;     // 栈底指针
} stack;// 创建栈的函数
stack* StackCreate() {// 开辟存储空间stack* p = (stack*)malloc(sizeof(stack));if (p == NULL)return NULL;  // 如果内存分配失败,返回NULLp->bottom = -1;  // 初始化bottom为-1,表示栈为空p->top = -1;     // 初始化top为-1,表示栈为空return p;
}// 入栈函数,在p栈尾插入a
void StackInput(stack* p, int a) {if (p->top < 99) {++(p->top);  // 栈顶指针加一p->data[p->top] = a;  // 赋值}else {printf("栈的空间不够了!!!\n");}
}// 出栈函数,在p栈尾出栈,并用a来存储
int StackOutput(stack* p, int* a) {if (p->top != -1) {  // 如果栈不为空*a = p->data[p->top];  // 赋值(p->top)--;  // 栈顶指针减一return 1;  // 成功出栈,返回1}return 0;  // 栈为空,返回0
}// 打印栈中所有元素的函数
void Print_function(stack* p) {for (int i = p->top; i >= 0; i--) {  // 从栈顶到栈底遍历printf("%d ", p->data[i]);  // 打印栈中的元素}printf("\n");
}int main() {int a, n, m;stack* p = StackCreate();  // 创建栈if (p == NULL) {printf("内存分配失败!\n");return 1;  // 如果创建栈失败,返回1}printf("请输入入栈个数:");scanf("%d", &n);  // 读取入栈的元素个数for (int i = 0; i < n; i++) {printf("请输入第%d个数:", i + 1);scanf("%d", &a);  // 读取用户输入的数字StackInput(p, a);  // 将数字入栈printf("入栈后:\n");Print_function(p);  // 打印当前栈的状态}printf("请输入出栈个数:");scanf("%d", &m);  // 读取出栈的元素个数for (int i = 0; i < m; i++) {int element;if (StackOutput(p, &element)) {  // 将栈顶元素出栈printf("出栈元素: %d\n", element);  // 打印出栈的元素}else {printf("栈已空,无法出栈!\n");}}printf("出栈后:\n");Print_function(p);  // 打印当前栈的状态free(p);  // 释放栈占用的内存return 0;
}

运行结果:

栈的链式存储代码表示(已给出具体代码的注释):

#define _CRT_SECURE_NO_WARNINGS  
#include <stdio.h>  
#include <stdlib.h>  // 定义链表节点结构体
typedef struct Node {int data;           // 存储的数据struct Node* next;  // 指向下一个节点的指针
} Node;// 定义栈结构体
typedef struct {Node* top;  // 栈顶指针
} stack;
// 创建栈的函数
stack* StackCreate() {stack* p = (stack*)malloc(sizeof(stack));if (p == NULL)return NULL;  // 如果内存分配失败,返回NULLp->top = NULL;    // 初始化栈顶指针为NULL,表示栈为空return p;
}
// 入栈函数,在p栈顶插入a
void StackInput(stack* p, int a) {Node* new_node = (Node*)malloc(sizeof(Node));if (new_node == NULL) {printf("内存分配失败!\n");return;}new_node->data = a;  new_node->next = p->top;  // 新节点的next指针指向当前栈顶p->top = new_node;  // 更新栈顶指针
}
// 出栈函数,在p栈顶出栈,并用a来存储
int StackOutput(stack* p, int* a) {if (p->top == NULL) { return 0;  // 返回0表示失败}Node* temp = p->top;  // 临时指针指向栈顶节点*a = temp->data;    p->top = temp->next;  // 更新栈顶指针free(temp);           // 释放栈顶节点的内存return 1;  // 成功出栈,返回1
}
// 打印栈中所有元素的函数
void Print_function(stack* p) {Node* current = p->top;  // 从栈顶开始遍历while (current != NULL) {printf("%d ", current->data);  // 打印栈中的元素current = current->next;       // 移动到下一个节点}printf("\n");
}
int main() {int a, n, m;stack* p = StackCreate();  // 创建栈if (p == NULL) {printf("内存分配失败!\n");return 1;  // 如果创建栈失败,返回1}printf("请输入入栈个数:");scanf("%d", &n);  // 读取入栈的元素个数for (int i = 0; i < n; i++) {printf("请输入第%d个数:", i + 1);scanf("%d", &a);  // 读取用户输入的数字StackInput(p, a);  // 将数字入栈printf("入栈后:\n");Print_function(p);  // 打印当前栈的状态}printf("请输入出栈个数:");scanf("%d", &m);  // 读取出栈的元素个数for (int i = 0; i < m; i++) {int element;if (StackOutput(p, &element)) {  // 将栈顶元素出栈printf("出栈元素: %d\n", element);  // 打印出栈的元素}else {printf("栈已空,无法出栈!\n");}}printf("出栈后:\n");Print_function(p);  // 打印当前栈的状态// 释放栈中所有节点的内存Node* current = p->top;while (current != NULL) {Node* temp = current;current = current->next;free(temp);}free(p);  // 释放栈结构体的内存return 0;
}

运行结果:

最后。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

听说点赞、收藏加关注的人都能长命千岁,万事如意。。。。。。。。。。。。。。。。。。。。


http://www.mrgr.cn/news/70919.html

相关文章:

  • Lua 实现继承的一种方式
  • ECharts柱状图-带圆角的堆积柱状图,附视频讲解与代码下载
  • wireshark使用lua解析自定义协议
  • (三)Ubuntu22.04+Stable-Diffusion-webui AI绘画 高质量的提示词插件安装
  • 从影视界看还要恢复大中型国企
  • 综合练习--轮播图
  • 【快捷入门笔记】mysql基本操作大全-SQL数据库
  • NVR批量管理软件/平台EasyNVR多个NVR同时管理基于端-边-云架构的智能视频融合云平台
  • 通过VirtualBox虚拟机安装和调试编译好的 ReactOS
  • 项目管理全流程平台(源码+文档+部署+讲解)
  • 慌慌张张匆匆忙忙,验证新人如何稳住
  • 光流法与直接法在SLAM中的应用
  • SQL Server Cross Apply 将某列分号的值转换多行
  • Linux文件以及文件夹操作命令 以及Linux文件夹含义最简单易懂的解释 Centos
  • Generator 函数的语法和用法
  • package.json中“type“: “module“是什么含义,es6和commonjs的区别以及require和import使用场景
  • ScheduledThreadPoolExecutor 定制化线程池任务调度底层原理
  • 一文了解什么是CNAPP
  • 京东关键词API接口获取
  • SpringBoot(十一)SpringBoot上传文件
  • 【Linux系统编程】第四十五弹---线程互斥:从问题到解决,深入探索互斥量的原理与实现
  • IOT物联网低代码可视化大屏解决方案汇总
  • runOnUiThread
  • .NET 公共语言运行时(Common Language Runtime,CLR)
  • MTSET可溶于DMSO、DMF、THF等有机溶剂,并在水中有轻微的溶解性,91774-25-3
  • python开发桌面应用(跨平台) 全流程