栈的实现:栈的链式实现、栈的数组实现、O(1)实现FindMin()、双向栈的实现
需要定义几个头文件:
fatal.h//实现错误处理
#include <stdio.h>
#include <stdlib.h>
#define FatalError(str) fprintf(stderr, "%s\n", str),exit(1)
stack.h//栈函数声明(用于栈的链式实现、栈的数组实现、O(1)实现FindMin())
#ifndef STACK_H
#define STACK_H
typedef int ElementType;
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode Stack;
int IsEmpty(Stack S);//栈是否为空
Stack CreateStack(void);//新建空栈
void ClearStack(Stack S);//清空栈
void DisposeStack(Stack *S);//销毁栈
void Push(ElementType X, Stack S);//X入栈
ElementType Pop(Stack S);//出栈并返回出栈元素
ElementType Peek(Stack S);//读取栈顶元素
ElementType FindMin(Stack S);//查找栈中最小元素,此功能只适用于第三种实现
#endif
stackmain.c//测试栈的实现(前三个都可以用此文件进行测试)
#include <stdio.h>
#include "stack.h"
#define M 10
int main(void)
{
Stack S;
int i;
S = CreateStack();
for(i = 10; i > 0; i -= 2)
Push(i, S);
for(i = 1; i <= M; i += 2)
Push(i, S);
while(!IsEmpty(S))
printf("%d : %d\n", Pop(S), FindMin(S));
printf("\n");
DisposeStack(&S);
return 0;
}
1. 栈的链式实现
#include "fatal.h"
#include "stack.h"
#include <assert.h>
struct Node
{
ElementType Data;//数据域
struct Node *Next;//指针域
};
int IsEmpty(Stack S)
{
return S->Next == NULL;
}
Stack CreateStack(void)
{
Stack S;
S = (PtrToNode)malloc(sizeof(struct Node));
S->Next = NULL;
return S;
}
void ClearStack(Stack S)
{
PtrToNode TmpCell, P;
P = S->Next;
S->Next = NULL;
while(P)
{
TmpCell = P->Next;
free(P);
P = TmpCell;
}
}
void DisposeStack(Stack *S)
{
PtrToNode P, TmpCell;
P = *S;
*S = NULL;
while(P)
{
TmpCell = P->Next;
free(P);
P = TmpCell;
}
}
void Push(ElementType X, Stack S)
{
PtrToNode TmpCell;
TmpCell = (Stack)malloc(sizeof(struct Node));
if(TmpCell == NULL)
FatalError("Out of space");
TmpCell->Data = X;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}
ElementType Pop(Stack S)
{
PtrToNode TmpCell;
ElementType X;
assert(0 == IsEmpty(S));
TmpCell = S->Next;
S->Next = TmpCell->Next;
X = TmpCell->Data;
free(TmpCell);
return X;
}
ElementType Peek(Stack S)
{
assert(0 == IsEmpty(S));
return S->Next->Data;
}
ElementType FindMin(Stack S)
{
return -1;
}
2. 栈的数组实现
#include "fatal.h"
#include "stack.h"
#include <assert.h>
#define EmptyToStack (-1)
#define INITIALSIZE 11
struct Node
{
ElementType *Array;//数组
int Capacity;//最大容量
int TopOfStack;//栈顶指针
};
int IsEmpty(Stack S)
{
return S->TopOfStack == EmptyToStack;
}
Stack CreateStack(void)
{
Stack S;
S = (Stack)malloc(sizeof(struct Node));
if(S == NULL)
FatalError("Out of space");
S->Array = (ElementType*)malloc(sizeof(ElementType) * INITIALSIZE);
if(S->Array == NULL)
FatalError("Out of space");
S->Capacity = INITIALSIZE;
S->TopOfStack = EmptyToStack;
return S;
}
void ClearStack(Stack S)
{
S->TopOfStack = EmptyToStack;
}
void DisposeStack(Stack *S)
{
if(*S != NULL)
{
free((*S)->Array);
free(*S);
*S = NULL;
}
}
void Push(ElementType X, Stack S)
{
if(S->TopOfStack == S->Capacity - 1)
{
S->Array = (ElementType *)realloc(S->Array, sizeof(ElementType) * (S->Capacity * 2));
if(S->Array == NULL)
FatalError("Out of space");
S->Capacity = S->Capacity * 2;
}
S->Array[++S->TopOfStack] = X;
}
ElementType Pop(Stack S)
{
assert(0 == IsEmpty(S));
return S->Array[S->TopOfStack--];
}
ElementType Peek(Stack S)
{
assert(0 == IsEmpty(S));
return S->Array[S->TopOfStack];
}
ElementType FindMin(Stack S)
{
return -1;
}
3. O(1)实现FindMin()查找栈中的最小元素
#include "fatal.h"
#include "stack.h"
#include <assert.h>
#define EmptyToStack (-1)
#define SIZE 11
struct Node
{
ElementType *Array;//数据栈
ElementType *Min;//存储最小元素的栈
int Capacity; //数据容量
int MinCapacity;//存放最小元素的栈
int TopOfStack;//数据栈栈顶指针
int TopOfMin;//最小元素栈栈顶指针
};
int IsEmpty(Stack S)
{
return S->TopOfStack == EmptyToStack;
}
Stack CreateStack(void)
{
Stack S;
S = (Stack)malloc(sizeof(struct Node));
if(S == NULL)
FatalError("Out of space");
S->Array = (ElementType *)malloc(sizeof(ElementType) * SIZE);
if(S->Array == NULL)
FatalError("Out of space");
S->Min = (ElementType *)malloc(sizeof(ElementType) * SIZE);
if(S->Min == NULL)
FatalError("Out of space");
S->Capacity = SIZE;
S->MinCapacity = SIZE;
S->TopOfStack = EmptyToStack;
S->TopOfMin = EmptyToStack;
return S;
}
void ClearStack(Stack S)
{
S->TopOfMin = EmptyToStack;
S->TopOfStack = EmptyToStack;
}
void DisposeStack(Stack *S)
{
if(*S != NULL)
{
free((*S)->Array);
free((*S)->Min);
free(*S);
*S = NULL;
}
}
void Push(ElementType X, Stack S)
{
if(S->TopOfStack == S->Capacity - 1)
{
S->Array = (ElementType *)realloc(S->Array, sizeof(ElementType) * (S->Capacity * 2));
if(S->Array == NULL)
FatalError("Out of space");
S->Capacity *= 2;
}
S->Array[++S->TopOfStack] = X;
if(S->TopOfMin == EmptyToStack)
S->Min[++S->TopOfMin] = X;
else if(X <= S->Min[S->TopOfMin])
{
if(S->TopOfMin == S->MinCapacity - 1)
{
S->Min = (ElementType *)realloc(S->Min, sizeof(ElementType) * (S->MinCapacity * 2));
if(S->Min == NULL)
FatalError("Out of space");
S->MinCapacity *= 2;
}
S->Min[++S->TopOfMin] = X;
}
}
ElementType Pop(Stack S)
{
ElementType X;
assert(0 == IsEmpty(S));
X = S->Array[S->TopOfStack--];
if(X == S->Min[S->TopOfMin])
S->TopOfMin--;
return X;
}
ElementType Peek(Stack S)
{
assert(0 == IsEmpty(S));
return S->Array[S->TopOfStack];
}
ElementType FindMin(Stack S)
{
assert(0 == IsEmpty(S));
return S->Min[S->TopOfMin];
}
4. 数组实现双向队列(跟前三个有所不同这里重新定义了stack.h并改名为DoubleStack.h)
DoubleStack.h
#ifndef STACK_H
#define STACK_H
typedef int ElementType;
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode Stack;
int IsEmpty(Stack S, int val);//0表示左边入栈,非零表示右边入栈
int IsFull(Stack S);
Stack CreateStack(void);
void ClearStack(Stack S);
void DisposeStack(Stack *S);
void Push(ElementType X, Stack S, int val);
ElementType Pop(Stack S, int val);
ElementType Peek(Stack S, int val);
#endif
DoubleStack.c//双向栈的具体实现
#include "fatal.h"
#include "stack.h"
#include <assert.h>
#define EmptyToStack (-1)
#define MAXCAPACITY (20)
#define INF -1
struct Node
{
ElementType *Array;
int TopOfFront;
int TopOfBack;
int Capacity;
};
int IsEmpty(Stack S, int val)
{
if(val)
return S->TopOfBack == S->Capacity;
else
return S->TopOfFront == EmptyToStack;
}
int IsFull(Stack S)
{
return S->TopOfBack == S->TopOfFront + 1;
}
Stack CreateStack(void)
{
Stack S;
S = (Stack)malloc(sizeof(struct Node));
if(S == NULL)
FatalError("Out of space");
S->Array = (ElementType *)malloc(sizeof(ElementType) * MAXCAPACITY);
if(S->Array == NULL)
FatalError("Out of space");
S->Capacity = MAXCAPACITY;
S->TopOfFront = EmptyToStack;
S->TopOfBack = S->Capacity;
return S;
}
void ClearStack(Stack S)
{
S->TopOfBack = S->Capacity;
S->TopOfFront = EmptyToStack;
}
void DisposeStack(Stack *S)
{
if(*S != NULL)
{
free((*S)->Array);
free(*S);
*S = NULL;
}
}
void Push(ElementType X, Stack S, int val)
{
if(!IsFull(S))
{
if(val)
S->Array[--S->TopOfBack] = X;
else
S->Array[++S->TopOfFront] = X;
}
//else
// FatalError("Stack is full");
}
ElementType Pop(Stack S, int val)
{
ElementType X = INF;
if(!IsEmpty(S, val))
{
if(val)
X = S->Array[S->TopOfBack++];
else
X = S->Array[S->TopOfFront--];
}
return X;
}
ElementType Peek(Stack S, int val)
{
ElementType X = INF;
if(!IsEmpty(S, val))
{
if(val)
X = S->Array[S->TopOfBack];
else
X = S->Array[S->TopOfFront];
}
return X;
}
DoubleStackMain.c//用于测试双向栈
#include <stdio.h>
#include "stack.h"
#define M 10
int main(void)
{
Stack S;
int i;
S = CreateStack();
for(i = 20; i > 0; i --)
Push(i, S, 0);
for(i = 1; i <= M; i += 2)
Push(i, S, 1);
printf("Left: ");
while(!IsEmpty(S, 0))
printf("%d ", Pop(S, 0));
printf("\nRight: ");
while(!IsEmpty(S, 1))
printf("%d ", Pop(S, 1));
putchar('\n');
DisposeStack(&S);
system("Pause");
return 0;
}