10. 栈
一、什么是栈
栈(Stack)是一种 后入先出(FILO - First In Last Out)的有序列表。栈中的元素的插入和删除只能在线性表的同一端进行,该位置是表的末端,叫做栈的顶。对栈的基本操作有 进栈(Push) 和 出栈(Pop),前者相当于插入,后者是删除最后插入的元素。栈有时又叫做 后进先出表(FIFO)。根据栈的定义可知,最先放入栈中元素在栈低,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素先删除,最先放入的元素最后删除。
ADT Stack
{
Data:
栈S∈Stack, 栈顶元素Item∈ElementType;
Operation:
Stack CreateStack(void); // 生成一个空的栈
int IsEmpty(Stack PtrS); // 栈是否为空
void Push(Stack PtrS, ElementType Item); // 压栈
ElementType Pop(Stack PtrS); // 出栈
ElementType Peek(Stack PtrS); // 查看栈顶元素
} ADT Stack;
二、栈的顺序存储实现
2.1、栈的顺序存储
#define MAX_SIZE 10
typedef int ElementType;
typedef struct QNode
{
int Data[MAX_SIZE];
int Front;
int Rear;
}QNode, * Queue;
2.2、创建空的栈
/**
* @brief 生成一个栈
*
* @return Stack 生成的栈
*/
Stack CreateStack(void)
{
Stack PtrS = (Stack)malloc(sizeof(SNode));
PtrS->Top = -1;
return PtrS;
}
2.3、判断栈是否为空
/**
* @brief 栈是否空
*
* @param PtrS 栈
* @return int 0: 栈非空; 1: 栈空;
*/
int IsEmpty(Stack PtrS)
{
return PtrS->Top == -1;
}
2.4、压栈
/**
* @brief 压栈
*
* @param PtrS 栈
* @param Item 要压栈的元素
*/
void Push(Stack PtrS, ElementType Item)
{
if (PtrS->Top == MAX_SIZE - 1)
{
printf("栈已满!\n");
return;
}
PtrS->Data[++PtrS->Top] = Item;
}
2.5、出栈
/**
* @brief 出栈
*
* @param PtrS 栈
* @return ElementType 要出栈的元素
*/
ElementType Pop(Stack PtrS)
{
if (PtrS->Top == -1)
{
printf("栈已空!\n");
return;
}
return PtrS->Data[PtrS->Top--];
}
2.6、获取栈顶元素
/**
* @brief 获取栈顶元素
*
* @param PtrS 栈
* @return ElementType 栈顶的元素
*/
ElementType Peek(Stack PtrS)
{
if (PtrS->Top == -1)
{
printf("栈已空!\n");
return NULL;
}
return PtrS->Data[PtrS->Top];
}
2.7、遍历栈
/**
* @brief 遍历栈中的元素
*
* @param PtrS
*/
void PrintStack(Stack PtrS)
{
for (int i = 0; i <= PtrS->Top; i++)
{
printf("%d ", PtrS->Data[i]);
}
printf("\n");
}
三、栈的链式存储实现
3.1、栈的链式存储
typedef int ElementType;
typedef struct SNode
{
ElementType Data;
struct SNode * Next;
}SNode, * Stack;
3.2、创建空的栈
/**
* @brief 创建空栈
*
* @return Stack 指向带头节点的空栈
*/
Stack CreateStack(void)
{
Stack PtrS = (Stack)malloc(sizeof(SNode));
PtrS->Data = 0;
PtrS->Next = NULL;
return PtrS;
}
3.3、 判断栈是否为空
/**
* @brief 判断栈是否为空
*
* @param S 栈
* @return int 0: 栈非空; 1: 栈为空
*/
int IsEmpty(Stack PtrS)
{
return PtrS->Next == NULL;
}
3.4、压栈
/**
* @brief 压栈
*
* @param PtrS 栈
* @param Item 要压栈的元素
*/
void Push(Stack PtrS, ElementType Item)
{
Stack NewNode = (SNode *)malloc(sizeof(SNode));
NewNode->Data = Item;
NewNode->Next = PtrS->Next;
PtrS->Next = NewNode;
}
3.5、出栈
/**
* @brief 出栈
*
* @param PtrS 栈
* @return ElementType 出栈的元素
*/
ElementType Pop(Stack PtrS)
{
Stack Item = NULL;
ElementType ItemData = 0;
if (PtrS->Next == NULL)
{
printf("栈为空\n");
return NULL;
}
Item = PtrS->Next;
ItemData = Item->Data;
PtrS->Next = Item->Next;
free(Item);
return ItemData;
}
3.6、获取栈顶元素
/**
* @brief 获取栈顶元素
*
* @param PtrS 栈
* @return ElementType 栈顶的元素
*/
ElementType Peek(Stack PtrS)
{
Stack Item = NULL;
ElementType ItemData = 0;
if (PtrS->Next == NULL)
{
printf("栈为空\n");
return NULL;
}
return PtrS->Next->Data;
}
3.7、遍历栈
/**
* @brief 遍历栈
*
* @param PtrS 栈
*/
void PrintStack(Stack PtrS)
{
if (PtrS == NULL)
{
return;
}
Stack Ptr = PtrS->Next;
while (Ptr != NULL)
{
printf("%d ", Ptr->Data);
Ptr = Ptr->Next;
}
printf("\n");
}