数据结构——栈(C语言版)

参考:数据结构学习——顺序栈和链式栈的简单实现和解析(C语言版)
作者:正弦定理
发布时间:2020-11-26 21:26:49
网址:https://blog.csdn.net/chinesekobe/article/details/110205257

一、概念

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

线性结构:有且仅有一个开始节点和一个终端节点,每个节点最多只有一个直接前驱和一个直接后继。代表结构:栈、队列
非线性结构:一个节点可能有多个直接前驱和多个直接后继。代表结构:树、图
堆栈(英语: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
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行稳方能走远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值