【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目

这篇具有很好参考价值的文章主要介绍了【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概念描述

栈是限定仅在表位进行插入或删除操作的线性表。栈的表尾称为栈顶,表头称为栈底。不含元素的栈称为空栈。

左图为栈的示意图,右图为用铁路调度表示栈。

【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目,数据结构,c++,visualstudio【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目,数据结构,c++,visualstudio

如下是入栈至栈满再进行出栈的过程示意图。值得注意的是,栈满后,top指针指向的不是顶端元素,而是顶端的下一个位置。

【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目,数据结构,c++,visualstudio

基本操作

构造一个空栈S

在正式开始前,照例需要定义一些如下的常量

#define STACK_INIT_SIZE 100//存储空间初始分配量
#define STACKINCREMENT 10//存储空间分配增量
#define TRUE 1
#define ERROR 0
#define OVERFLOW -2
typedef char SElemType;
tyoedef int Status;
typedef struct{
   SElemType *base;//栈底指针.在栈构造之前和销毁之后,base的值为NULL
   SElemType *top;//栈顶指针
   int stacksize;//当前已分配的存储空间,初始值一般为STACK_INIT_SIZE,不够时再以STACKINCREMENT为单位扩大
}SqStack;

在顺序栈中,base指针始终指向栈底元素,栈不存在的条件为base=NULLtop指针初值指向栈底,栈的条件为base==top。栈不空时,top指向(栈顶+1)。也就是说,在正常情况下,S.top 是不指向任何元素的。(top-base)的值即为栈中元素的个数,也即栈的长度。当top-base==stacksize时,说明栈满。此时若想进行入栈操作,需要扩充分配存储空间。

判空

Status StackEmpty(SqStack S)
{
  if(!S.base) return TRUE;
  else return FALSE;
}

构造一个空栈

Status InitStack(SqStack &S)
{
  S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
  if(!S.base) exit(OVERFLOW);
  S.top=S.base;
  S.stacksize=STACK_INIT_SIZE;
  return OK;
}

若栈不存在,分配空间时发生上溢出错误而退出。

入栈

在入栈、出栈、取栈顶元素的函数中,不存在分配空间的问题,是return ERROR而不是 exit(OVERFLOW)

Status Push(SqStack& S, SEIemType e)//入栈
{
	if (S.top - S.base >= S.stacksize) return ERROR;
	*S.top = e;//注意S.top是指针型变量
	S.top++;//先赋值,再加一
	return OK;
}

【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目,数据结构,c++,visualstudio

出栈

Status (SqStack &S)
{
 if(S.top==S.base) return ERROR;
 S.top--;
 e=*(S.top);
return OK;
}

值得注意的是,出栈后,元素e并未从栈中删除。改变的只是top指针的位置。虽然e还在栈中,但栈长已经改变,e的原位置此后可以被其它值覆盖。

【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目,数据结构,c++,visualstudio

取栈顶元素

取栈顶元素就是“top指针位置不变”版的“出栈”。博主初学时没意识到这一点,以为出栈就是删除元素,所以构造了一个很复杂的取栈顶元素函数。为避免误导,就不放在这里了。

Status(SqStack S,SElemType)
{
 if(S.top==S.base) return ERROR;
 e=*(S.top-1);//top指针位置不变
 return OK;
}

输出栈中所有元素

和取栈顶元素同理,在不移动指针位置的情况下输出元素。若采用for循环,需要先求栈长。一般使用while循环。

Status PrintStack(SqStack S)
{
 int i=0;
 SElemType *s;
 s=S.base;//注意!顺序栈从底部开始向上存储,顺序输出是从S.base开始
 //并且,如果想做逆序输出,while循环条件应为s!=S.base-1
 while(s!=S.top)
 {
  printf("%c\n",*s);
  s++;
  i++;
 }
 printf("已输出栈中%d个元素",i);
 return OK;
}
Status PrintStack(SqStack S)
{
 int a=S.top-S.base;
 if(S.base==S.top) return ERROR;
 int i;
 for(i=1;i<=a;i++)
    printf("%c\n",*(S.top-a));
 printf("已输出栈中%d个元素",a);
 return OK;
}

括号匹配

题干描述

由键盘输入一系列左括号和右括号,判断这些括号是否成功配对。一旦发现不配对的括号,立刻退出程序并说明原因。如:( { [ ] [ ] } )是匹配成功,而((]是由于括号不匹配而失败,{ ( [ ] )是因为左括号多余而失败,( { } ) ]是因为右括号多余而失败。

题目分析

【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目,数据结构,c++,visualstudio

代码(含分析)

Status March_Brackets(SqStack& S)
{
	char ch;//输入一连串字符(括号),以回车结束.起初,括号都存储在ch中,栈S为空栈.
	SElemType* s;
	s = S.top-1;//s指向栈顶元素
	printf("请输入字符:\n");
	ch = getchar();//输入括号,进入循环
	while (ch != '\n')//循环接收括号字符以回车为结束符,每输入一个括号,就进行一次判断。
	{
		if (ch =='(' || ch == '[' || ch == '{') //如果ch是左括号,入栈.栈中存放左括号,有匹配的右括号就出栈.若全部匹配成功,栈空。
			Push(S, ch); //入栈
			if (ch == ')')//输入字符为右括号
			{
				if ((Pop(S, *s) == 0)) { printf("右括号多余,不匹配\n"); return ERROR; }
				/*在Pop函数中, 若返回值为0, 说明是空栈.这有两种情况:1,还未输入左括号,第一个输入的就是右括号;
				2,之前输入的左、右括号都已成功匹配,左括号已全部出栈*/
				else if (*s != '(') { printf("右括号与左括号不匹配\n"); return ERROR; }
				/*最后输入的左括号不是小括号,与输入的右小括号不匹配*/
			}
			else if (ch == ']')
			{
				if ((Pop(S, *s) == 0)) { printf("右括号多余,不匹配\n"); return ERROR; }
				else if (*s != '[') { printf("右括号与左括号不匹配\n"); return ERROR; }
			}
			else if (ch == '}')
			{
				if ((Pop(S, *s) == 0)) { printf("右括号多余,不匹配\n"); return ERROR; }
				else if (*s != '{') { printf("右括号与左括号不匹配\n"); return ERROR; }
			}
			ch = getchar();
	}//循环结束,说明输入的右括号都有预支品牌的左括号.但这不意味着匹配成功!!还有左括号多余的可能。
	if (S.top != S.base)//栈不空,说明有左括号未出栈,未匹配
	{
		printf("左括号多余,不匹配\n");
		return ERROR;
	}
	else//栈空,说明左括号已全部出栈,匹配成功
	{
		printf("匹配完整,成功退出\n");
		return OK;
	}
} 

上机实现

完整代码

经高手指点:由于getchar的一些特性,建议只执行一次括号判断函数。不要在主函数中反复执行它。

#include <stdio.h>
#include <stdlib.h>
typedef char SElemType;
typedef int Status;
constexpr auto ERROR = 0;
constexpr auto OK = 1;
constexpr auto OVERFLOW = -2;
constexpr auto STACK_MAX_SIZE = 100;
typedef struct {
	SElemType* base;
	SElemType* top;
	int stacksize;
}SqStack;
Status InitStack(SqStack& S)//建立空顺序栈
{
	S.stacksize = STACK_MAX_SIZE;
	S.base = (SElemType*)malloc(STACK_MAX_SIZE * sizeof(SElemType));
	if (!S.base) exit(OVERFLOW);
	S.top = S.base;
	return OK;
}
Status Push(SqStack& S, SElemType e)//入栈
{
	if (S.top - S.base >= S.stacksize) exit(OVERFLOW);
	*S.top = e;//注意S.top是指针型变量
	S.top++;//先赋值,再加一
	return OK;
}
Status Pop(SqStack& S, SElemType& e)//出栈
{
	if (S.base == S.top) return ERROR;
	S.top--;//注意S.top是指针型变量
	e = *S.top;//先减一,再赋值
	return OK;
}
Status GetTop(SqStack S, SElemType &e)//获取栈顶元素
{
	if (S.top == S.base) return ERROR;
	e = *(S.top - 1);//top指针位置不变
	return OK;
}
Status PrintStack(SqStack S)//输出栈所有元素
{
	if (S.top == S.base) return ERROR;
	int i = 0;
	SElemType* s;
	s = S.base;
	while (s != S.top)
	{
		printf("%c\n", *s);
		i++;
		s++;
	}
	printf("已输出栈中%d个元素", i);
	return OK;

}
Status March_Brackets(SqStack& S)
{
	char ch;//输入一连串字符(括号),以回车结束.起初,括号都存储在ch中,栈S为空栈.
	SElemType* s;
	s = S.top-1;//s指向栈顶元素
	printf("请输入字符:\n");
	ch = getchar();//输入括号,进入循环
	while (ch != '\n')//循环接收括号字符以回车为结束符,每输入一个括号,就进行一次判断。
	{
		if (ch =='(' || ch == '[' || ch == '{') //如果ch是左括号,入栈.栈中存放左括号,有匹配的右括号就出栈.若全部匹配成功,栈空。
			Push(S, ch); //入栈
			if (ch == ')')//输入字符为右括号
			{
				if ((Pop(S, *s) == 0)) { printf("右括号多余,不匹配\n"); return ERROR; }
				/*在Pop函数中, 若返回值为0, 说明是空栈.这有两种情况:1,还未输入左括号,第一个输入的就是右括号;
				2,之前输入的左、右括号都已成功匹配,左括号已全部出栈*/
				else if (*s != '(') { printf("右括号与左括号不匹配\n"); return ERROR; }
				/*最后输入的左括号不是小括号,与输入的右小括号不匹配*/
			}
			else if (ch == ']')
			{
				if ((Pop(S, *s) == 0)) { printf("右括号多余,不匹配\n"); return ERROR; }
				else if (*s != '[') { printf("右括号与左括号不匹配\n"); return ERROR; }
			}
			else if (ch == '}')
			{
				if ((Pop(S, *s) == 0)) { printf("右括号多余,不匹配\n"); return ERROR; }
				else if (*s != '{') { printf("右括号与左括号不匹配\n"); return ERROR; }
			}
			ch = getchar();
	}//循环结束,说明输入的右括号都有预支品牌的左括号.但这不意味着匹配成功!!还有左括号多余的可能。
	if (S.top != S.base)//栈不空,说明有左括号未出栈,未匹配
	{
		printf("左括号多余,不匹配\n");
		return ERROR;
	}
	else//栈空,说明左括号已全部出栈,匹配成功
	{
		printf("匹配完整,成功退出\n");
		return OK;
	}
} 
int main(void)
{
	SqStack S; int i;
	char e; char f; char k;
	InitStack(S);
	printf("请向栈中输入字符\n");
	for (i = 0; i < 7; i++)
	{
		scanf_s("%c", &e);
		Push(S, e);//入栈
	}
	printf("已初始化栈如下\n");
	PrintStack(S);
	GetTop(S, f);//获取栈顶元素
	printf("栈顶元素为\n");
	putchar(f);
	printf("删除栈顶元素\n");
	Pop(S, k);//出栈
	printf("更新栈如下\n");
	PrintStack(S);

	printf("下面进入括号匹配\n");

    SqStack B;
	InitStack(B);
	March_Brackets(B);

	return 0;
}

运行结果

【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目,数据结构,c++,visualstudio文章来源地址https://www.toymoban.com/news/detail-732587.html

到了这里,关于【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】链栈的基本操作(C语言)

    零零总总搜索了一些关于链栈的资料,了解了链栈的基本操作,一直觉得别人写的代码或多或少存在一些问题,所以打算自己写一篇关于链栈的文章,也算是对所学知识的梳理和巩固了。 首先说明本文使用C语言进行链栈的基本操作,链栈是无头结点的。这里补充说明一下,

    2024年02月05日
    浏览(16)
  • 【数据结构】 链栈的基本操作 (C语言版)

    目录 一、链栈 1、链栈的定义: 2、链栈的优缺点: 二、链栈的基本操作算法(C语言)     1、宏定义   2、创建结构体 3、链栈的初始化   4、链栈的进栈 5、链栈的出栈 6、获取栈顶元素 7、栈的遍历输出 8、链栈的判空  9、求链栈的栈长 10、链栈的清空 11、链栈的销毁

    2024年01月24日
    浏览(15)
  • 数据结构学习——C语言对栈的基本操作

             栈(Stack)是一种常用的数据结构,遵循先进后出(LIFO)的原则,对表尾进行操作,常用于临时存储和撤销等操作,其基本操作包括栈的创建、入栈(也叫压栈Push)、出栈(又称弹栈)、栈的遍历、栈的清空(clear)、栈的销毁(destroy)等。         栈的创建有两种方式,一种是通

    2024年02月07日
    浏览(19)
  • 【数据结构】栈和队列(栈的基本操作和基础知识)

    🌈个人主页: 秦jh__ https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343 🔥 系列专栏: 《数据结构》 https://blog.csdn.net/qinjh_/category_12536791.html?spm=1001.2014.3001.5482 目录  前言 栈 栈的概念和结构 栈的实现 ​编辑 数组栈的实现 总的声明 初始化  插入 删除 取栈顶元素 销毁 判断是否为空

    2024年02月03日
    浏览(21)
  • 【Java】实现顺序表基本的操作(数据结构)

    在了解顺序表之前我们要先了解什么是线性表,线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构

    2024年02月03日
    浏览(16)
  • 数据结构教程实验一顺序表基本操作的实现

    1.掌握线性表的顺序存贮结构及基本操作,深入了解顺序表的基本特性,以便在实际问题背景下灵活运用它们。 2.深入理解和灵活掌握顺序表的插入、删除等操作。 1.硬件:每个学生需配备计算机一台。 2.软件:Windows操作系统+Visual C++。     1.将建表、遍历、插入、删除分别

    2024年02月07日
    浏览(20)
  • 【数据结构】顺序表基本操作的实现(C语言)

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:🛹数据结构、🛴C++ 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与

    2024年02月16日
    浏览(14)
  • 数据结构 线性表的定义和基本操作(以顺序表为例)

    名人说:一花独放不是春,百花齐放花满园。——《增广贤文》 作者:Code_流苏(CSDN) (一个喜欢古诗词和编程的Coder😊) 以下代码个人分享出来,仅供学习交流,且仅在CSDN平台发布,未经授权禁止二次转发。 〇、线性表是什么? 1、定义 线性表 是具有 相同数据类型 的 n(

    2024年02月12日
    浏览(20)
  • 数据结构:定长顺序串(SString)基本操作的算法描述(C语言)

    作者在学习数据结构时,发现鲜有完全按照 C 语言描述的算法操作,这让习惯于写 .c 而不是 .cpp 的初学者很是头疼。本文将基于 C 语言描述算法操作,如有错漏还望大佬们指正。 本文将按照严惠敏所著《数据结构(C语言版)》所做的函数原型声明进行算法描述,由于C语言不支

    2024年02月07日
    浏览(21)
  • 基于C语言的数据结构之顺序表——带你熟练掌握顺序表基本操作!!超级详细!!

    目录 前言: 1.源代码如下 2.数据结构——顺序表    2.1.顺序表的特点    2.2顺序表的分类     2.2.1.动态分配内存的顺序表     2.2.2.静态分配内存的顺序表    2.3.定义一个顺序表 3.顺序表的基本操作    3.1初始化顺序表     不用将顺序表中可能存在的原有元素初始化吗?

    2024年04月26日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包