栈的实现

栈的实现:栈的链式实现、栈的数组实现、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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值