【数据结构】顺序栈和链式栈的简单实现和解析(C语言版)

数据结构——栈的简单解析和实现
  • 一、概念
  • 二、入栈(push)
  • 三、出栈(pop)
  • 四、顺序栈简单实现
    • (1)进栈操作
    • (2)出栈操作

一、概念

本篇所讲解的栈和队列属于逻辑结构上的划分。逻辑结构分为线性结构、非线性结构

  • 线性结构:有且仅有一个开始节点和一个终端节点,每个节点最多只有一个直接前驱和一个直接后继。代表结构:栈、队列
  • 非线性结构:一个节点可能有多个直接前驱和多个直接后继。代表结构:树、图

堆栈(英语:stack)又称为栈或堆叠,是计算机科学中的一种抽象数据类型,只允许在有序的线性数据集合的一端(称为堆栈顶端,英语:top)进行加入数据(英语:push)和移除数据(英语:pop)的运算。因而按照后进先出(LIFO, Last In First Out)的原理运作。

  • 栈的主要特点就是LIFO(Last In First Out,后进先出),并且程序只能操作栈的一端,被操作的一端叫做栈顶(Top)。所以栈的使用非常简单,但是实现的功能却非常强大
  • 栈的主要操作有两个:入栈(push)、出栈(pop)

二、入栈(push)

在这里插入图片描述

  • 如图所示,栈就像一个瓶子,只有一个口。三个元素A、B、C先后入栈,先入栈的放在底部,后入栈的放在上面

三、出栈(pop)

在这里插入图片描述

  • 根据图示,栈顶的元素最先出栈。这与入栈的顺序刚好相反,入栈顺序是A->B->C,出栈顺序是C->B->A。也就是说:栈是LIFO(Last In First Out,后进先出的)
  • 看似简单的栈,应用十分广泛。操作系统的函数调用、各类编辑器的撤销操作的实现都离不开栈。

栈有两种实现方式:顺序栈链式栈

四、顺序栈简单实现

用数组实现栈,就是将数组的增、删操作限制在头部或者尾部,即只能在数组的一端操作元素,就成了顺序栈

前提准备:

typedef char ElementType;			//	进栈数据为字符型
typedef struct SNode {ElementType Data[MAXSIZE];		//	存放数据int Top; // 当前栈存放的数组的最大下标}SNode;typedef struct SNode* Stack;

(1)进栈操作

void Push(Stack PtrS, ElementType item) {	//	进栈 // 满的堆栈 Top == MAXSIZE - 1// 判断栈是否满if (PtrS->Top == MAXSIZE - 1) {printf("堆栈满\n");//	return Ptrs;}else {PtrS->Data[++(PtrS->Top)] = item;//	return;}
}

(2)出栈操作

ElementType Pop(Stack PtrS) {		//	出栈 // 空的的堆栈 Top == -1// 出栈需要判断 堆栈是否为空if (PtrS->Top == - 1) {printf("堆栈空\n");return -1;// ERROR 是 ElementType 的特殊值,标志错误}else {return PtrS->Data[(PtrS->Top)--];}
}

完整代码:

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<stdlib.h>#define MAXSIZE 10				//	设定栈的大小,以10个为例
#define ERROR NULL;	//typedef int ElementType;
typedef char ElementType;			//	进栈数据为字符型
typedef struct SNode {ElementType Data[MAXSIZE];		//	存放数据int Top; // 当前栈存放的数组的最大下标}SNode;typedef struct SNode* Stack;void Push(Stack PtrS, ElementType item);// 压栈
ElementType Pop(Stack PtrS);// 出栈void Init_Memu()			//	功能菜单 
{printf("******************************\n");printf("*        1.入栈              *\n");printf("*        2.出栈              *\n");printf("*        3.取栈顶元素        *\n");printf("*        4.判断是否栈空      *\n");printf("*        5.退出系统         *\n");printf("******************************\n");} int Chose_GongNeng()		//	选择功能 
{int i;printf("请选择你要实现的功能 : \n"); scanf("%d",&i);return i;} int main() {struct SNode ptr;		//	创建个结构体对象 int num;ptr.Top = -1;			//	栈空的标记符 为 -1while(1){	Init_Memu();num = Chose_GongNeng();switch(num){case 1:			//	入栈功能 {	//	int data;char data;ptr.Top = -1;while( ptr.Top != MAXSIZE-1 ){	printf("请输入数据 :\n");getchar();scanf("%c",&data);//	printf("count = %d\n",count);Push(&ptr,data);printf(" Top = %d\n",ptr.Top);} }break;case 2:			//	出栈功能 {	//	int Pop_Data = 0;char Pop_Data = '0';	while(1){Pop_Data = Pop(&ptr);if(ptr.Top == -1){printf("出栈完毕,现在栈为空栈\n");break;}else{printf("出栈数据为 : %c \n",Pop_Data);}}}break;case 3:			//	取栈顶元素 {	if(ptr.Top == -1){printf("出栈完毕,没有数据\n"); }else{printf("栈顶的数据为: %c \n",ptr.Data[ptr.Top]);}}break;case 4:			//	判断栈是否为空 {if(ptr.Top == -1){printf("此栈为空栈\n"); }else{printf("此栈已经插入数据\n");}}break;case 5:			//	退出系统 printf("\n谢谢你的使用\n");exit(-1);default:printf("没有这个功能,请重新选择\n");break; }}return 0;
}void Push(Stack PtrS, ElementType item) {	//	进栈 // 满的堆栈 Top == MAXSIZE - 1// 判断栈是否满if (PtrS->Top == MAXSIZE - 1) {printf("堆栈满\n");//	return Ptrs;}else {PtrS->Data[++(PtrS->Top)] = item;	//	进栈数据,记录并改变标记符Top//	return;}
}ElementType Pop(Stack PtrS) {		//	出栈 // 空的的堆栈 Top == -1// 出栈需要判断 堆栈是否为空if (PtrS->Top == - 1) {printf("堆栈空\n");return -1;// ERROR 是 ElementType 的特殊值,标志错误}else {return PtrS->Data[(PtrS->Top)--];	//	出栈数据,记录并改变标记符Top}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/466904.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GO 的 Web 开发系列(五)—— 使用 Swagger 生成一份好看的接口文档

经过前面的文章&#xff0c;已经完成了 Web 系统基础功能的搭建&#xff0c;也实现了 API 接口、HTML 模板渲染等功能。接下来要做的就是使用 Swagger 工具&#xff0c;为这些 Api 接口生成一份好看的接口文档。 一、写注释 注释是 Swagger 的灵魂&#xff0c;Swagger 是通过…

C++初阶:容器(Containers)list常用接口详解

介绍完了vector类的相关内容后&#xff0c;接下来进入新的篇章&#xff0c;容器list介绍&#xff1a; 文章目录 1.list的初步介绍2.list的定义&#xff08;constructor&#xff09;3.list迭代器&#xff08; iterator &#xff09;4.string的三种遍历4.1迭代器4.2范围for循环 5…

AI:126-基于深度学习的人体情绪识别与分析

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

【JavaEE】_CSS常用属性

目录 1. 字体属性 1.1 设置字体家族 font-family 1.2 设置字体大小 font-size 1.3 设置字体粗细 font-weight 1.4 设置字体倾斜 font-style 2. 文本属性 2.1 设置文本颜色 color 2.2 文本对齐 text-align 2.3 文本装饰 text-decoration 2.4 文本缩进 text-indent 2.…

Go+:一种简单而强大的编程语言

Go是一种简单而强大的编程语言&#xff0c;它是在Go语言之上构建的&#xff0c;旨在提供更加强大、灵活和易于使用的编程体验。Go与Go语言共享大部分语法和语义&#xff0c;因此Go开发人员可以很快上手Go&#xff0c;同时也可以使用Go来编写更加简洁和高效的代码。在本文中&…

【c语言】字符串常见函数 上

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;c语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&a…

Unity3d Shader篇(四)— Phong顶点高光反射着色器

文章目录 前言一、Phong顶点高光反射着色器是什么&#xff1f;1. Phong顶点高光反射着色器的工作原理2. Phong顶点高光反射着色器的优缺点优点缺点 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四、总…

99.网游逆向分析与插件开发-网络通信封包解析-数据包组织与发送过程逆向分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;定位明文发送数据的关键函数 首先来到下图位置&#xff0c;查看edi的值是怎样来的 然后使用高亮模式查看edi&#xff0c;看看谁给edi赋过值 首先是下图红框位置&#xff0c;mov ecx, edi也就是edi是一…

读千脑智能笔记12_阻止人类灭绝

1. 阻止人类灭绝 1.1. 宇宙中唯一知道这些的物体&#xff0c;唯一知道宇宙存在的物体&#xff0c;是我们的大脑 1.2. 如果没有关于某个事物的知识&#xff0c;我们能说这个事物就一定存在吗&#xff1f; 1.2.1. 我们的大脑扮演着这样一个独特的角色&#xff0c;这很令人着迷…

网络安全检查表

《网络攻击检查表》 1.应用安全漏洞 2.弱口令&#xff0c;默认口令 3.服务器互联网暴露 4.操作系统&#xff0c;中间件安全漏洞 5.研发服务器&#xff0c;邮件服务器等安全检查

《软件方法》强化自测题-杂项题目解析01

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 杂项&#xff08;1&#xff09; 3 [ 单选题 ] 《软件方法》第1章“建模和UML”开头所引用的歌曲&#xff0c;其词曲作者还写过下列歌曲中的&#xff1a; A) 爱江山更爱美人&#…

2024.2.3 作业

1、实现单向循环链表的头插头删尾插尾删 #include<stdio.h> #include<string.h> #include<stdlib.h> typedef int datatype; typedef struct node {//数据域int data;//指针域struct node *next; }*Linklist; Linklist create() {Linklist s(Linklist)mallo…