(一)栈的定义
栈是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈的顶。
对栈的基本操作有Push(进栈)和Pop(出栈),前者相当于插入,后者则是删除最后插入的元素。最后插入的元素可以通过使用Top例程在执行Pop之前进行考查。
栈的一般模型是,存在某个元素位于栈顶,而该元素是唯一可见的元素。
(二)栈的实现
1.栈的链表实现
在编写例程之前,我们先给出定义:
#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*/
struct Node
{
ElementType Element;
PtrToNode Next;
};
- IsEmpty函数
int IsEmpty( Stack S )
{
return S->Next == NULL;
}
- CreateStack函数
Stack CreateStack( void )
{
Stack S;
S = malloc( sizeof( struct 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 );
}
- Push函数
void Push( ElementType X, Stack S )
{
PtrToNode TmpCell;
TmpCell = malloc( sizeof( struct Node ) );
if( TmpCell == NULL )
FatalError( "Out of Space!!!" );/*如果指针为空,就退出程序*/
else
{
TmpCell->Element = X;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}
}
- Top函数
ElementType Top( Stack S )
{
if( !IsEmpty( S ) )
return S->Next->Element;
Error( "Empty stack" );
return 0;
}
- Pop函数
void Pop( Stack S )
{
PtrToNode FirstCell;
if( IsEmpty( S ) )
Error( "Empty stack" );
eles
{
FirstCell = S->Next;
S->Next = S->Next->Next;
free( FirstCell );
}
}
注意:栈的插入与删除,即Push和Pop都是对栈顶(表头)进行操作。
栈的链表实现的缺点是,对malloc和free的调用的开销是昂贵的。
栈的数组实现
在编写具体的例程之前,先定义要编写的函数:
#ifndef _Stack_h
struct StackRecord;
typedef struct 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( Stack S );/*从栈弹出元素的例程*/
ElementType TopAndPop( Stack S );
#endif
#define EmptyTOS ( -1 )
#define MinStackSize ( 5 )
struct StackRecord
{
int Capacity;
int TopOfStack;
ElementType *Array;
}
- CreateStack函数`
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)*MaxElements );
if( S->Array == NULL )
FatalError( "Out of space!!!" );
S->Capacity = MaxElements;
MakeEmpty( S );
return S;
}
- DisposeStack函数
void DisposeStack( Stack S )
{
if( S != NULL )
{
free( S->Array );
free( S );
}
}
- IsEmpty函数
int IsEmpty( Stack S )
{
return S->TopOfStack == EmptyTOS;
}
- IsFull函数
int IsFull( Stack S )
{
return S->TopOfStack == MaxElements-1;
}
- MakeEmpty函数
void MakeEmpty( Stack S )
{
S->TopOfStack = EmptyTOS;
}
- Push函数
void Push( ElementType X, Stack S )
{
if( IsFull( S ) )
Error( "Full Stack " );
else
S->Array[ ++S->TopOfStack ] = X;
}
- Top函数
ElementType Top( Stack S )
{
if( !IsEmpty( S ) )
return S->Array[ S->TopOfStack ];
Error( "Empty stack " );
return 0;
}
- Pop函数
void Pop( Stack S )
{
if( IsEmpty( S ) )
Error( "Empty stack" );
else
S->TopOfStack--;
}
- TopAndPop函数
ElementType TopAndPop( Stack S )
{
if( !IsEmpty( S ) )
return S->Array[ S->TopOfStack-- ];
Error( "Empty stack " );
return 0;
}
栈的数组实现唯一的危害是需要提前声明一个数组的大小。