栈模型
栈 (stack) 本质上可以描述成一个插入和删除只能在同一个位置上进行的链表,即表的末端(top)。栈的基本操作有 Push 和 Pop,前者相当于插入,后者是删除最后插入的元素。栈也可以被称作 LIFO 表。所以任何实现表的方法都可以用来实现栈结构。
这里给出两种主流的实现方法,指针和数组。
栈的链表实现
#ifndef _Stack_h
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode Stack;
int IsEmpty(Stack S);
Stack CreatStack(viod);
void DisposeStack(Stack S);
void MakeEmpty(Stack S);
ElementType Top(Stack S);
#endif /*_Stack_h*/
struct Node
{
ElementType Element;
PtrToNode Next;
};
int
IsEmpty(Stack S)
{
return S-Next == NULL;
}
测试栈是否为空
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)
Pop(S);
}
void
Pop(Stack S)
{
PtrToNode FirstCell;
if(IsEmpty(S))
Error("Empty stack");
else
{
FirstCell = S->Next;
S->Next = S->Next->Next;
free(FirstCell);
}
}
void
Push(Stack S, ElementType X)
{
PtrToNode TmpCell;
TmpCell = malloc(sizeof(struct Node));
if(TmpCell == NULL)
FatalError("Out of spce!!!");
else
{
TmpCell->Element = X;
TmpCell->Next = S->Next;
S->Next =TmpCell;
}
}
void
Top(Stack S)
{
PtrToNode FirstCell;
if (!IsEmpty(S))
return S->Next->Element;
Error("Empty Stack");
return 0;
}
通过对比链表结构,栈的操作基本上是一个常数,因为没有涉及到栈的循环。但是在分配内存的操作上会花费大量的时间。
栈的数组实现
栈的数组实现比较简单,因为它不涉及指针的操作,但是缺点在于必须提前声明一个数组的大小。
栈的应用:语法检测中括号匹配,后缀表达式。都是利用了栈的操作快速的特点。算法复杂度为 O(N) 的特点。