栈的插入和删除都只能在表的末端(栈顶)进行。
对栈的基本操作有Push(进栈)和Pop(出栈),前者用于插入,后者用于删除最后插入的元素。(栈是后进先出的表)
对空栈进行Pop是ADT错误。当空间用尽时,还在继续运行Push,则是一种实现错误。
栈的实现
一、链表实现
在用链表实现栈时,需要用到表头,通过在表的顶端插入来实现Push,通过删除表的顶端元素实现Pop,Top操作是用来返回栈顶元素值的一种操作。
创建一个空栈时,先建立一个头结点,用MakeEmpty设置Next指针指向NULL。Push操作向链表前段插入元素,其中表的前段即是栈顶;Top考察表的第一个元素;Pop用于删除表的第一个元素。
栈ADT链表实现的类型声明:
#ifndef _Stack_h
struct Node;
typedef struct Node* PtrToNode;
typedef PtrToNode Stack;
int IsEmpty(Stack S);
Stack CreateStack(void);
Void DisposeStack(Stack S);
Void MakeEmpty(Stack S);
Void Push(ElementType X, Stack S);
ElementType Top(Stack S);
Void Pop(Stack S);
#endif /* _Stack_h */
//Place in implementation file
//Stack implementation is a linked list with a header
struck Node
{
ElementType Element;
PtrToNode Next;
};
栈ADT链表实现:
int
IsEmpty(Stack S)
{
return S->Next == NULL;
}
Stack
CreateStack(void)
{
Stack S;
S = malloc(sizeof(struck Node));
if(S == NULL)
FatalError("Out of space !");
S->Next == Null;
MakeEmpty(S);
return S;
}
void
MakeEmpty(Stack S)
{
if(S == NULL)
Error("Must use CreateStack first !");
else
while(!IsEmpty(S))
Pop(S);
}
Void
Push(ElementType X, Stack S)
{
PtrToNode TmpCell;
TmpCell = malloc(sizeof(struck Node));
if(TmpCell == NULL)
FatalError("Out of space !");
else
{
TmpCell->Element = X;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}
}
ElementType
Top(Stack S)
{
if(!IsEmpty(S))
return S->Next->Element;
Error("Empty stack");
return 0; //Return value used to avoid warning
}
void
Pop(Stack S)
{
PtrToNode FirstCell;
if(IsEmpty(S))
Error("Empty stack");
else
{
FirstCell = S->Next;
S->Next = S->Next->Next; //始终保持S的栈顶位置。
free(FirstCell);
}
}
二、栈的数组实现:
在栈的数组实现中,每个栈都有一个TopOfStack,当栈为空时,TopOfStack=-1, 当要将元素X压入栈中时,将TopOfStack加1,然后置Stack [TopOfStack] = X。当要弹出栈元素时,将Stack[TopOfStack]返回,并将TopOfStack减1.
栈的数组实现的声明:
#ifndef _Stack_h
struct StackRecord;
typedef struck stackRecord* Stack;
int IsEmpty(Stack S);
int IsFull(Stack S)';
Stack CreateStack(int MaxElements);
void DisposeStack(Stack S);//用于释放栈结构,先释放栈数组,然后释放栈结构体。
Void MakeEmpty(Stack S);
Void Push(ElementType X, Stack S);
ElementType Top(Stack S);
void Pop(Strack S);
ElementType TopAndPop(Stack S);
#endif //_Stack _h
//Place in implementation file
//Stack implementation is a dynamically allocated array
#define EmptyTOS(-1);
#define MinStackSize(5)
struct StackRecor
{
int Capacity;
int TopOfStack;
ElementType* Array;
};
栈的数组实现:
Stack
CreateStack(int MaxElements)
{
Stack S;
if (MaxElements<MinStackSize)
Error("Stack size is too small");
S = malloc(sizeof(struct StackRecord));
if( S == NULL)
FatalError("Out of space !");
S->Array = malloc(sizeof(ElementType)*MaxElemnts);
if(S->Array == NULL)
FatalError("Out of space !");
S->Capacity = MaxElements;
MakeEmpty(S);
return S;
}
Void
DisposeStack(Stack S)
{
if(S != NULL)
{
free(S->Array);
free(S);
}
}
int
IsEmpty(Stack S)
{
return S->TopOfStack == EmptyTOS;
}
Void
MakeEmpty(Stack S)
{
S->TopOfStack = EmptyTOS;
}
Void
Push(ElementType X, Stack S)
{
if(IsFull(S))
Error("Full Stack");
else
S->Array[++S->TopOfStack] = X;
}
ElementType
Top(Stack S)
{
if(!IsEmpty(S)
return S->Array[S->TopOfStack];
Error("Empty stack");//有问题吗?
return 0;//Return value used to avoid warning
}
void
Pop(Stack S)
{
if(IsEmpty(S))
Error("Empty stack");
else
S->TopOfStack--;
}
ElemnetType
TopAndPop(Stack S)
{
if(!IsEmpty(S))
return S->Array[S->TopOfStack--];
Error("Empty stack");
return 0; //Return value used to avoid warning
}