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

news2024/11/25 16:20:57
数据结构——栈的简单解析和实现
  • 一、概念
  • 二、入栈(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;			//	栈空的标记符 为 -1
	while(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.coloradmin.cn/o/1449367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GPDB - 高可用 - FTS机制(一):探测成功

GPDB - 高可用 - FTS机制&#xff08;一&#xff09;&#xff1a;探测成功 作为GreenPlum高可用的核心功能&#xff0c;FTS&#xff08;Fault Tolerance Server&#xff09;进程负责故障检测。该进程是master上的一个子进程&#xff0c;可以快速检测到primary或者mirror是否宕机…

PyTorch深度学习快速入门教程 - 【小土堆学习笔记】

小土堆Pytorch视频教程链接 声明&#xff1a; 博主本人技术力不高&#xff0c;这篇博客可能会因为个人水平问题出现一些错误&#xff0c;但作为小白&#xff0c;还是希望能写下一些碰到的坑&#xff0c;尽力帮到其他小白 1 环境配置 1.1 pycharm pycharm建议使用2020的&…

【C语言】指针的进阶篇,深入理解指针和数组,函数之间的关系

欢迎来CILMY23的博客喔&#xff0c;本期系列为【C语言】指针的进阶篇&#xff0c;深入理解指针和数组&#xff0c;函数之间的关系&#xff0c;图文讲解其他指针类型以及指针和数组&#xff0c;函数之间的关系&#xff0c;带大家更深刻理解指针&#xff0c;以及数组指针&#xf…

LeetCode Python - 16.最接近的三数之和

目录 题目答案运行结果 题目 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,2,1,-4],…

Vulnhub靶场 DC-6

目录 一、环境搭建 二、主机发现 三、漏洞复现 1、wpscan工具 2、后台识别 dirsearch 3、爆破密码 4、rce漏洞利用 activity monitor 5、rce写shell 6、新线索 账户 7、提权 8、拿取flag 四、总结 一、环境搭建 Vulnhub靶机下载&#xff1a; 官网地址&#xff1a…

凭证获取:Linux凭证获取

目录 shadow文件详解 1.Shadow文件的组成与作用 2.破解Shadow文件内容 利用strace记录密码 shadow文件 1.Shadow文件的组成与作用 在Linux中&#xff0c;/etc/shadow文件又被称为“影子文件”&#xff0c;主要用于存储Linux文件系统中的用户凭据信息。该文件只能由root权…

【日常聊聊】新年新征程:迎接学习的挑战

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 结语 我的其他博客 前言 随着新的一年的到来&#xff0c;程序员们站在了全新的起点。这是一个充满机遇和挑战的时刻&#xff0…

【C++初阶:类和对象(下篇)】初始化列表 | static成员 | 友元

目录 一、构造函数构造函数体赋值&#x1f43e;初始化列表&#x1f43e;&#x1f4a6; explicit关键字 二、static成员&#x1f43e;概念**&#x1f4a6; 关于静态的特性** 三、友元&#x1f4a6; **友元函数**&#x1f4a6; **友元类** **四、内部类** 一、构造函数 构造函数…

Spring 事务原理总结四

作为一名认知有限的中国人&#xff0c;我对年的喜爱&#xff0c;胜过其他一切&#xff0c;因为它给了我拒绝一切的合理理由。每到这个时候&#xff0c;我都会用各种理由来为自己的不作为开脱&#xff0c;今年亦是如此。看着频频发出警报的假期余额&#xff0c;我内心的焦躁变得…

分布式文件系统 SpringBoot+FastDFS+Vue.js【一】

分布式文件系统 SpringBootFastDFSVue.js【一】 一、分布式文件系统1.1.文件系统1.2.什么是分布式文件系统1.3.分布式文件系统的出现1.3.主流的分布式文件系统1.4.分布式文件服务提供商1.4.1.阿里OSS1.4.2.七牛云存储1.4.3.百度云存储 二、fastDFS2.1.fastDSF介绍2.2.为什么要使…

详解CC++内存管理(new和delete)

文章目录 写在前面1. C&C内存分布2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3. C内存管理方式&#xff08;语法&#xff09;3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4. new和delete的实现原理4.1 operator new与operator delete…

【MySQL】学习外键约束处理员工数据

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-g4glZPIY0IKhiTfe {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

STM32—DHT11温湿度传感器

文章目录 一.温湿度原理1.1 时序图 二.代码 一.温湿度原理 1.1 时序图 (1).下图一是DHT11总的时序图。 (2).图二对应图一的左边黑色部分&#xff0c;图三对应图一的绿色部分&#xff0c;图四的左部分图对应图一的红色部分&#xff0c;图四的右部分对应图一的黄色部分。 (3)…

计算机组成原理(1)----主存储器

目录 1.基本半导体元件及原理 2.寻址 1.基本半导体元件及原理 一个主存储器可以分为存储器&#xff0c;MAR&#xff08;地址寄存器&#xff09;和MDR&#xff08;数据寄存器&#xff09;&#xff0c;这三个部件由在时序控制逻辑的控制下工作 其中存储体用来存放二进制数据0和…

[BIZ-缓存] - 3.金融交易系统缓存架构设计

1. 前置文章 [BIZ] - 1.金融交易系统特点https://blog.csdn.net/besthezhaowen/article/details/136118133 [缓存] - 1.缓存共性问题https://blog.csdn.net/besthezhaowen/article/details/136111466 [缓存] - 2.分布式缓存重磅中间件 Redis-CSDN博客文章浏览阅读1.4k次&…

docker (一)-简介

1.什么是docker Docker 是一个开源的应用容器引擎&#xff0c;由于docker影响巨大&#xff0c;今天也用"Docker" 指代容器化技术。 2.docker的优势 一键部署&#xff0c;开箱即用 容器使用基于image镜像的部署模式&#xff0c;image中包含了运行应用程序所需的一…

【Java程序员面试专栏 分布式中间件】ElasticSearch 核心面试指引

关于ElasticSearch 部分的核心知识进行一网打尽,包括ElasticSearch 的基本概念,基本架构,工作流程,存储机制等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 基础概念 从数据分类入手,考察全文索引的基本概念 现实世界中数据有哪…

【教程】Kotlin语言学习笔记(二)——数据类型(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【Kotlin语言学习】系列文章 第一章 《认识Kotlin》 第二章 《数据类型》 文章目录 【Kotlin语言学习】系列文章一、基本数据…

机器学习和统计学的区别?

1、本质区别&#xff1a; 目标&#xff1a;机器学习的核心目标是建立一个可以自动学习和改进的模型&#xff0c;以预测未知数据。它更关注结果的准确性和模型的泛化能力&#xff0c;通常不关心模型是否可以解释。而统计学的目标是探究变量之间的关系&#xff0c;理解数据的内在…

Python数据科学:Scikit-Learn机器学习

4.1Scikit-Learn机器学习 Scikit-Learn使用的数据表示&#xff1a;二维网格数据表 实例1&#xff1a;通过Seaborn导入数据 def skLearn():scikit Learn基本介绍:return:import seaborn as sns#导入Iris数据集#注&#xff1a;一般网络访问不了iris sns.load_dataset(iris)ir…