目录
四、堆栈
1、定义
具有一定操作约束的线性表
特点:
(1)只在一端(栈顶,Top)做插入,删除
(2)插入数据:入栈(Push)
(3)删除数据:出栈(Pop)
(4)先入后出:Last In First Out(LIFO)
2、堆栈的抽象数据类型描述
类型名称:堆栈(Stack)
数据对象集:一个有0个或者多个元素的有穷线性表
操作集:长度为MaxSize的堆栈SStack,堆栈元素itemElementType
Stack CreateStack(int MaxSize);//生成空堆栈,其最大长度为MaxSize
int IsFull(Stack S,int MaxSize);//判断堆栈S是否已满
void Push(Stack S,ElementType item);//将元素item压入堆栈
int IsEmpty(Stack S);//判断堆栈是否为空
ElementType Pop(Stack S);//删除并返回栈顶元素
五、栈的顺序存储实现
栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成
1、定义结构体
#define MaxSize 100//<存储数据元素的最大值>
typedef struct SNode *Stack;
struct SNode
{
ElementType Data[MaxSize];
int Top; //栈顶的数组下标位置
};
2、入栈
//入栈
void Push(Stack PtrS,ElementType item)
{
if(PtrS->Top==MaxSize-1)
{
printf("堆栈满");
return;
}
else
{
PtrS->Data[++(PtrS->Top)]=item;
return;
}
}
3、出栈
//出栈
ElementType Pop(Stack PtrS)
{
if(PtrS->Top==-1)
{
print("堆栈空");
return ERROR; //ERROR可以是ElementType的特殊值,用于标志错误
}
else
return (PtrS->Data[(Ptrs->Top)--]);
}
4、例子
使用一个数组实现两个堆栈,要求最大化利用数组空间,使得数组只要有空间入栈操作就可以成功。
解决方法:使两个栈分别从数组两头开始,当两个栈的栈顶相遇时,表示两个栈都满了
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define MaxSize 100//<存储数据元素的最大值>
typedef struct DStack *Stack;
struct DStack
{
ElementType Data[MaxSize];
int Top1; //堆栈1栈顶的数组下标位置
int Top2;//堆栈2栈顶的数组下标位置
}S;
S.Top1=-1;
S.Top2=MaxSize;
int main(int argc, char** argv) {
return 0;
}
//入栈
void Push(Stack PtrS,ElementType item,int Tag)
{
if(PtrS->Top2-PtrS->Top1==1)
{
printf("堆栈满");return ;
}
if(Tag==1)
{
PtrS->Data[++(PtrS->Top1)]=item;
}
else
{
PtrS->Data[--(PtrS->Top2)]=item;
}
}
//出栈
ElementType Pop(Stack PtrS,int Tag)
{ //Tag用于区分两个堆栈的标志,取值为1、2
if(Tag==1) //对第一个堆栈操作
{
if(PtrS->Top1==-1)//堆栈1空
{
printf("堆栈1空");return NULL;
}
else return PtrS->Data[(PtrS->Top1)--];//返回栈顶1元素
}
else if(Tag==2)//对第二个堆栈操作
{
if(PtrS->Top2==MaxSize)//堆栈2空
{
printf("堆栈2空");return NULL:
}
else return PtrS->Data[(PtrS->Top2)++];//返回栈顶2元素
}
else
{
printf("堆栈序号选择错误");return NULL;
}
}
六、堆栈的链式存储实现
栈的链式存储结构实际上是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。栈顶指针一定得是链表的表头,在表头位置插入或者删除结点。
1、定义结构体
typedef struct SNode *Stack;
struct SNode
{
ElementType Data;
struct SNode *Next;
};
2、创建堆栈头结点
Stack CreateStack()
{
Stack S;
S=(Stack)malloc(sizeof(struct SNode));//创建一个堆栈头结点,返回指针
S->Next=NULL:
return S;
}
3、判断是否为空栈
int IsEmpty(Stack S)
{
return (S->Next==NULL);//判断堆栈S是否为空,若为空,函数返回整数1,否则返回0
}
4、入栈
void Push(ElementType item,Stack S)
{
//将元素item压入堆栈S
Stack Tmpcell;
Tmpcell=(Stack)malloc(sizeof(struct SNode));
Tmpcell->Data=item;
Tmpcell->Next=S->Next
s->Next=Tmpcell;
}
5、出栈
ElementType Pop(Stack S)
{
struct SNode *FirstCell;
ElementType TopElem;
if(IsEmpty(s))//判断是否为空栈
{
printf("堆栈空");
return NULL;
}
else
{
FirstCell=S->Next;
S->Next=FirstCell->Next;
TopElem=FirstCell->Data;
free(FirstCell);
return TopElem;
}
}
6、堆栈的应用
① 应用堆栈实现后缀表达式求值的基本过程
②将中缀表达式转换为后缀表达式
③函数调用以及递归实现
④深度优先搜索
⑤回溯算法
数据结构的奇妙冒险持续更新中~
要是文章有帮助的话
就点赞收藏关注一下啦!
感谢大家的观看
欢迎大家提出问题并指正~