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