《数据结构与算法》(浙大MOCC)2.3堆栈

堆栈是一种后入先出的数据结构,常用于处理如中缀表达式转换等计算问题。本文介绍了堆栈的定义,包括其在解决优先级计算问题中的应用,并详细阐述了堆栈的顺序存储和链式存储实现方式,讨论了入栈、出栈操作以及如何用链表实现堆栈。
摘要由CSDN通过智能技术生成

2.3堆栈

2.3.1堆栈的定义

引:
问题——电脑计算复杂顺序算术式的优先级

  • 中缀表达式:5+6/2-3*4
  • 后缀表达式(栈):5 6 2 / + 3 4 *-
  • 算法:当连续出现数字时,记住这个数字序列,遇到符号时取出离符号最近的两个数字运算,重复这个过程
  • 实现:管理一个序列,对该序列的主要操作是在序列的末尾插入元素和删除(取出)元素。

堆栈(Stack)

  • 定义
    可以认为是具有一定约束的线性表,插入和删除操作都作用在一个称为栈顶(Top)的位置。
  • 特性
    数据插入(Push):压入栈;
    数据删除(Pop):弹出栈;
    后入先出(Last In First Out,LIFO)。
  • 数据对象集
    一个有0个或者多个元素的有穷线性表。
  • 操作集
    (1)Stack CreatStack(int MaxSize):生成空栈,最大长度为MaxSize;
    (2)bool IsFull(Stack S):判断栈是否已经堆满
    (3)void Push(Stack S, ElementType X):将元素押入栈内
    (4)bool IsEmpty(Stack S):判断栈是否为空,是返回1否则0
    (5)ElementType Pop(Stack S):删除并且返回栈顶元素。若堆栈为空,返回错误信息,否则将栈顶数据元素从堆栈中删除并返回

2.3.2堆栈的实现

1.栈的顺序存储实现

  • 描述栈类型(Stack)
typedef int Position;
typedef struct SNode*PtrToSNode;
struct SNode{
	ElementType * Data;/*存储元素的数组*/
	Position Top;/*栈顶指针*/
	int MaxSize;/*堆栈最大容量*/
}typedef PtrToSNode Stack;
  • 顺序栈的创建
Stack CreatStack(int MaxSize)
{
	Stack S=(Stack)malloc(sizeof(struct SNode));
	S->Data=(ElementType*)malloc(MaxSize*sizeof(ElementType));
	S->Top=-1;
	S->MaxSize=MaxSize;
	return S;
}
  • 入栈
void Push(Stack PtrS, ElementType item)
{
	if(PtrS->Top==MAXSIZE-1){
		printf("栈堆满")return;
	}
	else{
		PtrS->Data[++(PtrS->Top)]=item;
		return;
	}
}

PtrS->Data[++(PtrS->Top)]=item;即:
(PtrS->Top)++;
PtrS->Data[PtrS->Top]=item;

  • 出栈(返回数组中下标为Top的值,同时Top–)
ElementType Pop(Stack PtrS)
{
	if(PtrS->To==-1){
		printf("堆栈空")return 	ERROR;
		}
	else
		return (PtrS->Data[(PtrS->Top)--]);//先return,再-1,注意单目运算符的位置
}	

用一个数组实现两个堆栈

  • 要点:使这两个栈分别从数组的两头开始向中间生长,当两个栈的栈顶指针相遇时,表示两个栈都满了
  • 实现:
#define MaxSize
struct DStack{
	ElementType Data[MaxSize];
	int Top1;/*堆栈1的栈顶指针*/
	int Top2;/*堆栈2的栈顶指针*/
}S;
S.Top1=-1;
S.Top2=MaxSize;
/*指针跑到外面时两个堆栈都为空*/
  • 入栈(要点:区分堆栈——Tag)
void Push(struct DStack *PtrS, ElementType item, int Tag)
{
	if(PtrS->Top2-PtrS->Top1==1){/*栈堆满*/
		printf("栈堆满")return;
	}
	else if(Tag==1)/*对第一个堆栈操作*/
		PtrS->Data[++(PtrS->Top1)]=item;
	else/*对第二个堆栈操作*/
		PtrS->Data[--(PtrS->Top2)]=item;
	}
  • 出栈
ElementType Pop(struct DStack *PtrS, int Tag)
{
	if(Tag==1){/*对第一个堆栈操作*/
	if(PtrS->Top1==-1){
		printf("堆栈1空")return NULL;
		}
	else return PtrS->Data[(PtrS->Top1)--];
	}
	else{
		if(PtrS->Top2==MaxSize){
			printf("堆栈2空")return NULL;
			}
		else return PtrS->Data[(PtrS->Top2)++];
	}
}		

2.堆栈的链式存储实现

  • 栈的链式存储结构实际上是一个单链表,叫做链栈。
  • 插入和删除只能在链栈的栈顶进行
  • 栈顶指针Top指向链表的更加方便
typedef struct SNode *Stack;
struct SNode{
	ElementType Data;
	struct SNode*Next;
}

(1)堆栈初始化(建一个空栈);

(2)判断堆栈S是否为空

Stack CreatStack()
{/*构建一个堆栈的头结点,返回指针*/
	Stack S;
	S=(Stack)malloc(sizeof(struct SNode));
	S->Next=NULL;
	return S;
}

int IsEmpty(Stack S)
{/*判断堆栈S是否为空,若为空则返回1,否则返回0*/
	return (S->Next == NULL);
}
  • 入栈(头插)
    [注:不需要判断是否满栈,因为是链表而不是数组]
void Push( ElementType item ,Stack S)
{
	Stack TmpCell;
	TmpCell=(struct SNode*)malloc(sizeof(struct SNode));
	TmpCell->Element=item;
	TmpCell->Next=S->Next;
	S->Next=TmpCell;
}
  • 出栈
ElementType Pop(Stack S)
{/*删除并返回堆栈的栈顶元素*/
	Stack FirstCell;
	ElementType TopElem;
	if(IsEmpty(S)){
		printf("堆栈空")return NULL;
		}
	else{
		FirstCell=S->Next;
		S->Next= FirstCell->Next;
		TopElem=FirstCell->Element;
		free(FirstCell);
		return TopElem;
	}
}

实际上
这里的S是一个哨兵结点,真正的栈顶是S->Next

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值