栈,一种线性表,先进后出,重要的数据结构之一。最近在写语法分析器的时候,在求FIRSTVT和LASTVT的时候,发现自己栈操作方面挺薄弱的。故在此积累一下。
1.操作一维数组
即将一维数组中的值入栈、出栈、取栈顶元素
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 10
//数据结构定义
typedef struct{
char data[MAXSIZE];
int top;
}SeqStack;
//函数声明
SeqStack *InitSeqStack();
int EmptySeqStack(SeqStack *);
int PushSeqStack(SeqStack*,char);
int PopSeqStack(SeqStack*,char *);
char TopSeqStack(SeqStack*);
//主函数
int main(void){
char str[5]={'a','b','c','d','e'};
SeqStack *s;
s=InitSeqStack();
int i,a;
//入栈
for(i=0;i<5;i++){
a=PushSeqStack(s,str[i]);
printf("第%d个元素的入栈结果是:%d\n",i,a);
}
//出栈
int x;
char y;
x=PopSeqStack(s,&y);
printf("出栈结果为:%d\n",x); //是否pop成功
printf("出栈的元素为:%c\n",y); //输出pop出来的值
//取栈顶元素
char b=TopSeqStack(s);
printf("栈顶元素为:%c",b);
return 0;
}
//置空栈
SeqStack *InitSeqStack(){
SeqStack *s;
s=malloc(sizeof(SeqStack));
s->top=-1;
return s;
}
//判空
int EmptySeqStack(SeqStack *s){
if(s->top==-1){
return 1;
}else{
return 0;
}
}
//入栈
int PushSeqStack(SeqStack *s,char x){
if(s->top==MAXSIZE-1){
return 0; //栈满不能入栈
}else{
s->top++;
s->data[s->top]=x;
return 1;
}
}
//出栈
int PopSeqStack(SeqStack *s,char *x){
if(EmptySeqStack(s)){
return 0;
}else{
*x=s->data[s->top];
s->top--;
return 1;
}
}
//取栈顶元素
char TopSeqStack(SeqStack *s){
if(EmptySeqStack(s)){
return 0;
}else{
return s->data[s->top];
}
}
运行结果如下:
2.操作二维字符数组
即将二维字符数组中的每一行入栈、出栈、取栈顶元素
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 10
typedef struct SeqStack{
char *data[MAXSIZE];
int top;
}SeqStack;
struct SeqStack *InitSeqStack();
int EmptySeqStack(SeqStack*);
int PushSeqStack(SeqStack*,char*);
int PopSeqStack(SeqStack*,char*);
char* TopSeqStack(SeqStack*);
int main(void){
char str[5][3]={"aa\0","bb\0","cc\0","dd\0","ee\0"};
SeqStack *s = NULL;
s=InitSeqStack();
int i,a;
//入栈
for(i=0;i<5;i++){
a=PushSeqStack(s,str[i]);
printf("第%d个元素入栈的结果:%d\n",i,a);
}
//取栈顶元素
char *b;
b=TopSeqStack(s);
printf("栈顶的元素是%s\n",b);
//出栈
char *c;
int m=PopSeqStack(s,c);
printf("出栈的结果:%d\n",m);
// printf("出栈的元素是:%s\n",c);
//取栈顶元素
b=TopSeqStack(s);
printf("栈顶的元素是%s",b);
return 0;
}
//置空栈
struct SeqStack *InitSeqStack(){
SeqStack *s;
s=(struct SeqStack*)malloc(sizeof(struct SeqStack));
s->top=-1;
return s;
}
//判空
int EmptySeqStack(SeqStack *s){
if(s->top==-1){
return 1;
}else{
return 0;
}
}
//入栈
int PushSeqStack(SeqStack *s,char *x){
if(s->top==MAXSIZE-1){
return 0; //栈满不能入栈
}else{
s->top++;
s->data[s->top]= x;
return 1;
}
}
//出栈
int PopSeqStack(SeqStack *s,char *x){
if(EmptySeqStack(s)){
return 0;
}else{
x=s->data[s->top];
s->top--;
return 1;
}
}
//取栈顶元素
char* TopSeqStack(SeqStack *s){
if(EmptySeqStack(s)){
return 0;
}else{
return s->data[s->top];
}
}
运行结果如下:
3.两个代码的对比
1.前者是将一维数组入栈,后者是将二维数组入栈。那么后者在前者的基础上进行了哪些修改呢?
当然最主要的就是数据结构的定义部分啦!
typedef struct{
char data[MAXSIZE];
int top;
}SeqStack;
typedef struct SeqStack{
char *data[MAXSIZE];
int top;
}SeqStack;
区别就在于后者要定义一个指针类型的数据段,这样才能存二维字符数组的某一行。
2.值得注意的是:取栈顶元素的函数中,返回的是一个char * 类型,用来指示该栈顶元素的指针。调用的时候应该这样写:
char *b;
b=TopSeqStack(s);
printf("栈顶的元素是%s\n",b);
基本上就是这样啦!以后继续补充…