一、顺序栈的实现

顺序栈利用到顺序表的一些知识,当然你可以联想到数组,把其中一端固定为base,这里我们采用严蔚敏《数据结构》中的规范--空递增的方式。栈满后可以利用realloc拓展。

具体实现代码如下:

#include<stdio.h>
#include<stdlib.h>

//******宏定义参数******
#define OK 1
#define NO 0
#define STACK_MAX_SIZE 20

//******定义数据类型别名******
typedef int Status;
typedef char ElemType;
typedef double db;

//******声明数据结构******
typedef struct node
{
	ElemType ch;
	int StackSize;
	struct node *base;
	struct node *top;
}SqStack,*StackPoint;

StackPoint InitStack()
{
	StackPoint p=NULL;
	p=(StackPoint)malloc(sizeof(SqStack));
	if(!p)
	{
		printf("头结点内存申请失败!\n");
		return p;
	}
	p->base=NULL;
	p->base=(StackPoint)malloc(STACK_MAX_SIZE*sizeof(SqStack));
	p->StackSize=0;
	if(!(p->base))
		printf("栈内存申请失败!\n");
	else
	{
		p->top=p->base;
		p->StackSize=STACK_MAX_SIZE;
		printf("栈内存申请成功!\n");
	}
	return p;
}

Status StackEmpty(StackPoint Head)
{
	if(Head->base == Head->top)
		return OK;
	return NO;
}

Status Extend(StackPoint Head)
{
	StackPoint p;
	int size=Head->StackSize;
	p=(StackPoint)realloc(Head->base,(size+STACK_MAX_SIZE)*sizeof(SqStack));
	if(p==NULL)
	{
		printf("动态内存申请失败!\n");
		return NO;
	}
	else
	{
		Head->base=p;
		Head->StackSize=size+STACK_MAX_SIZE;
	}
	return OK;
}

ElemType getTop(StackPoint Head)
{
	if(StackEmpty(Head))
	{
		printf("该栈为空栈!\n");
		return NO;
	}
	return (Head->top-1)->ch;
}

void StackPush(StackPoint Head,ElemType ch)
{
	if(Head->top-Head->base>=Head->StackSize && !Extend(Head))
	{
		printf("\"%c\"入栈失败!\n",ch);
		return ;
	}
	Head->top++->ch=ch;
	return ;
}

void StackPop(StackPoint Head)
{
	if(StackEmpty(Head))
	{
		printf("警告!当前栈为空,出栈失败!\n");
		return ;
	}
	Head->top--;
	printf("出栈成功!\n");
	return ;
}

int main()
{
	StackPoint Head;
	int i;
	Head=InitStack();
	for(i=0;i<4;i++)
		StackPush(Head,'A'+i);
	for(i=0;i<4;i++)
	{
		printf("%c\n",getTop(Head));
		StackPop(Head);
	}
	free(Head->base);
	free(Head);
	return 0;
}

二、链式栈

利用链表的结构实现,可以实时地增加和减少内存(要多少给多少),不会造成空间浪费。每一块内存指针指向它栈内存的前驱。

具体实现代码如下:

#include<stdio.h>
#include<stdlib.h>

/*
    利用顺序栈的方法声明一个链栈的结构体
    链栈的性质均与链栈相似
*/

//******宏定义参数******
#define OK 1
#define NO 0
#define STACK_MAX_SIZE 20

//******定义数据类型别名******
typedef int Status;
typedef char ElemType;
typedef double db;

//******声明数据结构******
typedef struct node
{
	ElemType ch;
	struct node *next;
}SqStack,*StackPoint;

typedef struct
{
	int StackSize;
	StackPoint base;
	StackPoint top;
}HeadNode,*HeadPoint;

HeadPoint InitStack()
{
	HeadPoint Head=(HeadPoint)malloc(sizeof(HeadNode));
	Head->StackSize=0;
	Head->base=Head->top=(StackPoint)malloc(sizeof(SqStack));
	return Head;
}

Status StackEmpty(HeadPoint Head)
{
	if(Head->base == Head->top)
		return OK;
	return NO;
}

ElemType getTop(HeadPoint Head)
{
	if(StackEmpty(Head))
	{
		printf("对不起,该栈为空!\n");
		return NO;
	}
	return (Head->top->next)->ch;
}

void StackPush(HeadPoint Head,ElemType ch)
{
	StackPoint p=(StackPoint)malloc(sizeof(SqStack));
	if(p==NULL)
	{
		printf("对不起,系统内存不足!入栈失败!\n");
		return ;
	}
	Head->top->ch=ch;
	p->next=Head->top;
	Head->top=p;
	Head->StackSize++;
	return ;
}

void StackPop(HeadPoint Head)
{
	StackPoint p=Head->top;
	if(StackEmpty(Head))
	{
		printf("对不起,当前栈为空,无内容可出栈!\n");
		return ;
	}
	Head->StackSize--;
	Head->top=p->next;
	free(p);
	return ;
}

void StackDelete(HeadPoint Head)
{
	while(!StackEmpty(Head))
		StackPop(Head);
	free(Head->base);
	return ;
}

int main()
{
	ElemType ch;
	HeadPoint Head;
	Head=InitStack();
	printf("%s\n",StackEmpty(Head)?"该栈为空!":"该栈非空!");
	while((ch=getchar())!='\n')
		StackPush(Head,ch);
	printf("%s\n",StackEmpty(Head)?"该栈为空!":"该栈非空!");
	while(!StackEmpty(Head))
	{
		printf("%c",getTop(Head));
		StackPop(Head);
	}
	printf("\n%s\n",StackEmpty(Head)?"该栈为空!":"该栈非空!");
	StackDelete(Head);
	free(Head);
	printf("链栈操作结束!\n");
	return 0;
}

总结:

栈的这两种表示形式各有优劣,但假如你知道数据的规模的话不妨选择顺序栈,这里可以定义一个结构体数组,简单方便易实现。栈这种“先进后出”的模式在计算机中有着非常广泛的应用,程序设计中递归就是一个很经典的例子,目前可以利用栈的数据结构完成“迷宫”、“表达式求值”的功能。代码日后补。