栈的实现一般由数组与链表实现,但数组实现较为常见,链表实现一般不常用。以下给出两种实现方式的完整代码:
一、数组实现
注意要点:
1. 栈为空时 Top = -1;
2. 栈满时 Top = Capacity;
代码如下:
/* ADT: Stack
存储结构:数组
*/
struct StackRecord;
typedef StackRecord *Stack;
struct StackRecord
{
int Capacity; // 栈的容量
int TopOfStack;
ElementType *Array;
};
#define EmptyTOS ( -1 )
#define MinStackSize ( 5 )
Stack CreatStack( int MaxElements );
int IsEmpty( Stack S );
int IsFull( Stack S );
void MakeEmpty( Stack S );
void Dispose( Stack S );
void Push( ElementType X, Stack S );
void Pop( Stack S );
ElementType Top( Stack S );
ElementType TopAndPop( Stack S );
/* 基本操作实现 */
Stack CreatStack(int MaxElements)
{
// 初始条件:输入栈的容量
// 操作结果:创建并返回一个最大容量为Max_Element的空栈
Stack S;
if ( MaxElements< MinStackSize )
printf("Stack size is too small!!!");
S = (Stack) malloc( sizeof(struct StackRecord) );
if ( NULL == S )
{
printf( "Out of sapce!!!" );
return NULL;
}
S->Array =( ElementType * )malloc( sizeof(ElementType) * MaxElements );
if ( NULL == S->Array )
{
printf( "Out of Space!!!" );
return NULL;
}
S->Capacity = MaxElements;
MakeEmpty( S );
return S;
}
void DisposeStack( Stack S )
{
// 操作结果:删除栈
if ( S != NULL )
{
free( S->Array );
free( S );
}
}
int IsEmpty( Stack S )
{
// 操作结果:判断栈是否为空栈
// EmptyTos为一个值,栈为空时TopOfStack = EmptyTOS;
return S->TopOfStack == EmptyTOS;
}
int IsFull( Stack S )
{
// 操作结果:判断栈是否满
return S->TopOfStack == S->Capacity;
}
void MakeEmpty( Stack S )
{
// 操作结果:设置Top指针为0,清空栈
S->TopOfStack = EmptyTOS;
}
void Push( ElementType X, Stack S )
{
// 操作结果:栈未满时将数据元素X进栈
if ( IsFull(S) )
printf( "Full Stack" );
else
{
S->TopOfStack++;
S->Array[S->TopOfStack] = X;
}
}
void Pop( Stack S )
{
// 操作结果:若栈不为空,顶端元素出栈
if ( IsEmpty(S) )
printf( "Empty Stack" );
else
S->TopOfStack--;
}
ElementType Top(Stack S)
{
// 操作结果:返回栈顶元素的值
if ( IsEmpty(S) )
{
printf( "Empty Stack" );
return 0; /* return value used to avoid warming */
}
else
return S->Array[S->TopOfStack];
}
ElementType TopAndPop( Stack S )
{
if ( IsEmpty(S) )
{
printf( "Empty Stack" );
return 0; /* return value used to avoid warming */
}
else
return S->Array[S->TopOfStack--];
}
链表实现时以Top为头指针,指向带头结点单链表的头结点,Push、Pop等操作在表头完成。
当 Top->Next = NULL时栈为空。
代码如下:
/*
ADT: 栈
实现:带头结点的单链表
*/
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode Stack;
struct Node
{
ElementType Element;
PtrToNode Next;
};
/* 基本操作 */
Stack CreatStack( );
void DisposeStack( Stack S );
int IsEmpty( Stack S );
void MakeEmpty( Stack S );
void Push( ElementType X, Stack S );
void Pop( Stack S );
ElementType Top( Stack S );
Stack CreatStack( )
{
// 操作结果:返回空栈
Stack S;
S = ( Stack )malloc( sizeof(struct Node) );
if ( NULL == S )
{
printf("Out of Space!!!");
return NULL;
}
S->Next = NULL;
MakeEmpty( S );
return S;
}
void DisposeStack( Stack S )
{
// 操作结果:删除栈
if ( S !== NULL )
{
MakeEmpty( S );
free( S );
}
}
int IsEmpty( Stack S )
{
// 操作结果:判断栈是否为空
return NULL == S->Next;
}
void MakeEmpty( Stack S )
{
// 操作结果:清空栈
if ( NULL == S )
printf("Must create stack first!");
else
while ( !IsEmpty(S) )
Pop( S );
}
void Push( ElementType X, Stack S )
{
// 操作结果:使元素X入栈
PtrToNode TmpCell;
TmpCell = ( PtrToNode) malloc( sizeof(struct Node) );
if ( NULL == TmpCell )
{
printf("Out of space!!!");
return;
}
TmpCell->Element = X;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}
void Pop( Stack S )
{
// 操作结果:若栈不为空,则使顶端元素出栈
PtrToNode FirstCell;
if ( IsEmpty(S) )
printf("Empty Stack");
else
{
FirstCell = S->Next;
S->Next = FirstCell->Next;
free( FirstCell );
}
}
ElementType Top( Stack S )
{
// 操作结果:若栈不为空,则返回栈顶元素
if ( !IsEmpty(S) )
return S->Next->Element;
printf( "Empty Stack" );
return 0;
}