栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
允许插入和删除的一端称为栈顶(top),另一端称为栈底(botton),不含任何数据元素的栈称为空栈。栈又称为“后进先出”的线性表,简称LIFO结构。
栈可以用顺序结构实现,也可以用链式结构实现。
顺序栈
/*
顺序栈,使用顺序表实现栈结构,
将顺序表的表尾当作栈的头和尾。
可以使出栈和入栈的的时间复杂度都降为O(1)
定义top=-1为栈空
栈的基础操作
(1)入栈
(2)出栈
(3)查看栈顶元素
(4)判断栈满
(5)判断栈空
(6)栈的长度
(7)初始化
(8)清空栈
*/
#define MIXSIZE 5
typedef int ElemType;
typedef struct
{
ElemType data[MIXSIZE];
int top;
}OrderStack;
//初始化栈
void initOrderStack(OrderStack* stack);
//判断栈空
bool orderStackEmpty(OrderStack stack);
//判断栈满
bool orderStackFill(OrderStack stack);
//入栈
bool orderStackPush(OrderStack* stack,ElemType value);
//出栈
bool orderStackPop(OrderStack* stack);
//获取栈定元素
ElemType getOrderStackTop(OrderStack stack);
//获取栈的长度
int getOrderStackLength(OrderStack stack);
//清空栈
void clearOrderStack(OrderStack* stack);
#include "orderStack.h"
void initOrderStack(OrderStack* stack)
{
stack->top = -1;
}
bool orderStackEmpty(OrderStack stack)
{
return stack.top == -1 ? true : false;
}
bool orderStackFill(OrderStack stack)
{
return stack.top == MIXSIZE - 1 ? true : false;
}
bool orderStackPush(OrderStack* stack, ElemType value)
{
bool bRet=false;
if (!(orderStackFill(*stack)))
{
stack->data[++stack->top] = value;
bRet = true;
}
return bRet;
}
bool orderStackPop(OrderStack* stack)
{
bool bRet = false;
if (!(orderStackEmpty(*stack)))
{
--stack->top;
bRet = true;
}
return bRet;
}
ElemType getOrderStackTop(OrderStack stack)
{
if (!(orderStackEmpty(stack)))
{
return stack.data[stack.top];
}
}
int getOrderStackLength(OrderStack stack)
{
return stack.top+1;
}
void clearOrderStack(OrderStack* stack)
{
stack->top = -1;
}
顺序栈使用是非常方便的,但是由于顺序结构本身的特点,即事先必须确定存储空间的大小,这就使的顺序栈有些不那么完美。这是就产生了两个栈公用一段连续的存储空间的结构。
typedef int ElemType;
typedef struct
{
ElemType data[MIXSIZE];
int top1;
int top2;
}OrderStack;
第一个栈的栈顶为数组头,第二个栈的栈顶为数组尾,这样就实现了两栈公用一块存储空间。同样也可以多栈公用一块存储空间。
链栈
/*
使用链式结构实现栈
栈其实是一种特殊的链表,特殊之处在于支持头插和头删(将链表头作为栈顶)
(1)初始化
(2)栈空(链栈不存在栈满)
(3)压栈
(4)弹栈
(5)取栈顶元素
(6)销毁链表
(7)栈的长度
*/
#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LLStack
{
ElemType data;
LLStack* next;
}StackNode;
typedef struct
{
StackNode* headNode;
int length;
}LStack;
//初始化
void initLinkListStack(LStack* stack);
//判断栈空
bool linkListStackEmpty(LStack stack);
//压栈
void linkListStackPush(LStack* stack,ElemType value);
//弹栈
bool linkListStackPop(LStack* stack);
//取栈顶元素
StackNode* getLinkListStackTop(LStack stack);
//销毁链表
void deteleLinkListStack(LStack* stack);
//栈的长度
int getLinkListStackLength(LStack stack);
#include "linkListStack.h"
void initLinkListStack(LStack* stack)
{
stack->headNode = NULL;
stack->length= 0;
}
bool linkListStackEmpty(LStack stack)
{
return stack.headNode == NULL ? true : false;
}
void linkListStackPush(LStack* stack, ElemType value)
{
StackNode* node = (StackNode*)malloc(sizeof(StackNode));
node->data = value;
node->next = stack->headNode;
stack->headNode = node;
stack->length++;
}
bool linkListStackPop(LStack* stack)
{
bool bRet = false;
if (!(linkListStackEmpty(*stack)))
{
StackNode* node = stack->headNode;
stack->headNode = stack->headNode->next;
free(node);
node = NULL;
bRet = true;
stack->length--;
}
return bRet;
}
StackNode* getLinkListStackTop(LStack stack)
{
return stack.headNode;
}
void deteleLinkListStack(LStack* stack)
{
while (linkListStackPop(stack));
}
int getLinkListStackLength(LStack stack)
{
return stack.length;
}
栈的应用有很多,一般有表达式求值,递归。