一、堆栈的定义
堆栈可以认为是 具有一定约束的 线性表,插入和删除操作 都作用在一个称为 栈顶(Top)的端点位置。
对堆栈的主要操作是 在序列的末尾插入元素和删除元素。
通常把数据插入叫做 压入栈,而数据删除叫做 弹出栈。
所以最后入栈的数据将最先弹出,因此堆栈也被称为 后入先出表。
二、堆栈的实现
有顺序和链式两种形式。
1、栈的顺序存储实现
顺序栈类型:
typedef int Position;
typedef struct SNode* PtrToSNode;
struct SNode
{
ElementType * Data; //存储元素的数组
Position Top; //栈顶指针
int MaxSize; //堆栈最大容量
};
typedef PtrToSNode Stack;
定容量的空堆栈的创建:
Stack CreateStack(int MaxSize) //创建堆栈
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data (ElementType*)malloc(MaxSize*sizeof(ElementType));
S->Top = -1;
S->MaxSize = MaxSize;
return S;
}
入栈操作Push
bool IsFull(Stack S)
{
return(S->Top == S->MaxSize -1);
}
bool Push(Stack S, ElementType X) //入栈
{
if(IsFull) //先判断是否满了
{
printf("堆栈满\n");
return false;
}
else
{
S->Data [++(S->Top )] = X; //先S->Top+1,再Data赋值
return true;
}
}
出栈操作Pop
bool IsEmpty(Stack S)
{
return (S->Top == -1);
}
ElememtType Pop(Stack S)
{
if(IsEmpty(S)) //先判断里面是否有元素
{
printf("堆栈空\n");
return ERROR; //返回错误标识
}
else
return ( S->Data[(S->Top)--] ); //先取数,再Top--
}
2、堆栈的链式存储实现
栈的链式存储结构与单链表类似,但其操作受限制,插入和删除操作只能在链栈的栈顶进行。
栈顶指针Top就是链表的头指针。
有时为了简便算法,链栈也可以带一空的 表头结点,表头结点后面的第一个结点就是 链栈的栈顶结点,栈中的其他结点 通过他们的指针Next链接起来,栈底结点的Next为NULL。
用C语言表示链栈:
typedef struct SNode * PtrToSNode;
struct SNode
{
ElememtType Data;
PtrToSNode Next;
};
typedef PtrToSNode Stack;
带头结点的链栈的主要操作:
Stack CreateStack() //构建一个堆栈的头结点,返回该结点指针
{
Stack S;
S = (Stack)malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}
bool IsEmpty(Stack S) //判断链栈是否为空
{
return (S->Next == NULL);
}
bool Push(Stack S, ElememtType X)
{
PtrToSNode TmpCell;
TmpCell=(PtrToSNode)malloc(sizeof(struct SNode));
TmpCell->Data = X;
TmpCell->Next = S->Next ; //入栈
S->Next = TmpCell; //栈顶指针
return true;
}
ElememtType Pop(Stack S)
{
PtrToSNode FirstCell; //用一个指针来指出栈顶指针的下一个空间
ElememtType TopElem;
if(IsEmpty(S))
{
printf("堆栈空\n");
return ERROR;
}
else
{
FirstCell = S->Next ;
TopElem=FirstCell->Next ;
S->Next = FirstCell->Next ;
free(FirstCell); //清除构造的指针
return TopElem;
}
}