数据结构---栈和队列

栈的定义和特点

栈 (stack) 是限定仅在表尾进行插入或删除操作的线性表

表尾->栈顶;表头->栈底

image-20220113152908091

相当于出口入口是同一个,所以先进后出(LIFO),这种模型适用于按照保存数据时相反的顺序来使用

队列的定义和特点

队列(queue)是一种先进先出(First In First Out, FIFO)的线性表。

可以插入的一端->队尾;可以删除的一端->队头

image-20220113153430886

相当于出口和入口不相同,所以先进先出(FIFO),这种模型适用于按照先保存数据先使用的顺序

案例 模型 具体
数制的转换 求余运算,第一次所得余数为转换后数的最低位,最后一次为最高位,符合先进后出
括号匹配的检验 圆括号和方括号,其嵌套顺序随意且正确,第一个压栈后,若下一个和它不匹配就继续压,直到出现括号匹配则去掉这两个匹配成功的,而去掉的这个顺序就是括号匹配顺序的正解
表达式求值 算符(运算符和界限符)优先算法
舞伴问题 队列 先入队的男士或女士应先出队配成舞伴,符合先进先出

其中实现表达式求值,需要设置两个栈,一个存运算符(OPTR),一个存运算数和运算结果(OPND)

按照自左向右的顺序扫描表达式的每一个字符

  • 扫描到运算数,压入栈OPND

  • 扫描到运算符

    1. 若运算符比OPTR栈顶运算符优先级高,则入栈
    2. 若运算符比OPTR栈顶运算符优先级低,则从OPND栈中弹出两个运算数,从OPTR中弹出栈顶运算符进行运算并将运算结果压入栈OPND。
  • 继续处理当前字符,直到遇到结束符

eg: 3+7*6-1

OPND OPTR
3 +
7 *
6 -优先级低于* ,所以弹出6,7进行*运算
42 -
1

其中实现舞伴问题,需要设置两个队列,依次将队头元素出队配成舞伴,某队为空,则另外一队等待着下一舞曲第一个可以获得舞伴的人

栈的表示和操作的实现

栈的类型定义

ADT Stack

{

数据对象:D={ai I ai属于ElemSet, i=l, 2,...,n,n>=0}

数据关系:R= { < ai-1, ai > I ai-1,ai属于D, i=2,…,n}

基本操作:

}ADT Stack

栈本身就是线性表,有顺序存储和链式存储两种存储方式

顺序栈的表示和实现

利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针 top指示栈顶元素在顺序栈中的位置。

#define MAXSIZE 100 //存储空间初始分配量
typedef struct

{

SElemType *base; //栈底指针

SElemType *top; //栈顶指针

int stacksize;栈可用的最大容量

}SqStack;

空栈:栈顶和栈底指向同一位置

栈满:top-base==stacksize(两个指针相减的得到的是两个指针之间所存元素的个数)

image-20220113164440867

插入新元素指针top增1,删除新元素指针top减1,指针base位置不动

1.初始化

算法步骤:

  • 为顺序栈动态分配一个最大容最为M心(SIZE 的数组空间, 使 base 指向这段空间的基地址, 即栈底。
  • 栈顶指针 top 初始为 base, 表示栈为空。
  • stacksize 置为栈的最大容量MAXSIZE

注意空间是否分配成功

2.入栈

算法步骤:

  • 判断栈是否满, 若满则返回ERROR。
  • 将新元素压入栈顶, 栈顶指针加1。

栈顶指针加1:* S.top++=e

相当于:*S.top=e;S.top++;先把e赋给top指针指向的值,再将top指针向上挪一位

3.出栈

算法步骤:

  • 判断栈是否空, 若空则返回ERROR。
  • 栈顶指针减1, 栈顶元素出栈。

栈顶指针减1:e=*--S.top

相当于:--S.top;e=*S.top;先把top指针向下挪一位(top指针指向栈顶上面一个元素),再将top指针指向的值赋给e,因为top-base之间的元素少了一个,所以top指针指向的为空

4.取栈顶元素

因为top指针实际一般指向栈顶元素的上一位,所以直接返回S.top-1的值

代码实现

#include<iostream>
using namespace std;
#define MAXSIZE 100   //存储空间初始分配量
typedef int SElemType;
//顺序栈的存储结构
typedef struct
{
	SElemType* base;   //栈底指针
	SElemType* top;   //栈顶指针
	int stacksize;   //可用最大容量
}SqStack;

//初始化
void InitStack(SqStack& S)
{
	S.base = new SElemType[MAXSIZE];
	if (!S.base) exit;
	S.top = S.base;
	S.stacksize = MAXSIZE;
}

//入栈
int Push(SqStack& S, SElemType e)
{
	if (S.top - S.base == S.stacksize) return 0;	//栈满
	*S.top = e;
	S.top++;
	return 1;
}

//出栈
int Pop(SqStack& S, SElemType& e)
{
	if (S.top == S.base) return 0;    //栈空
	S.top--;
	e = *S.top;
	return 1;
}

//取栈顶元素
SElemType GetTop(SqStack S)
{
	if (S.top != S.base)	 //非栈空时返回
		return *(S.top - 1);  
}

//输出栈
void printStack(SqStack S)
{
	cout << "栈:" << endl;
	SElemType* p = S.base;
	while (p != S.top)
	{
		cout<< *p;
		p++;
	}
	cout << endl;
}

int main()
{
	SqStack S;
	int e;
	InitStack(S);
	cout<<"请输入一个要入栈的元素(-1表示结束):";
	cin>>e;
	while (e != -1)
	{
		Push(S, e);
		cout<<"请输入一个要入栈的元素(-1表示结束):";
		cin >> e;
	}
	printStack(S);
	Pop(S, e);
	printStack(S);
	e = GetTop(S);
	cout << "取出的栈顶元素为:" << e << endl;
}

posted on 2022-02-06 19:53  眉目作山河  阅读(190)  评论(0编辑  收藏  举报

导航