栈的基本操作
包含九个基本操作
如下:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/malloc.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int ElemType;
typedef int Status;
//栈的顺序结构表示
typedef struct {
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
//1.构建一个空栈
Status InitStack(SqStack *S){
S->base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
if(!S->base){
printf("存储分配失败");
exit(-1);
}
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;
return OK;
}
//2.进栈
Status Push(SqStack *S,ElemType e){
if(S->top-S->base>=STACK_INIT_SIZE){
S->base=(ElemType *)realloc(S->base, (S->stacksize+STACKINCREMENT)*sizeof(ElemType));
if(!S->base)
return ERROR;
S->top=S->base+STACK_INIT_SIZE;//栈底地址可能改变,重新定位栈顶元素
S->stacksize=S->stacksize+STACKINCREMENT;
}
*S->top=e;
S->top++;
return OK;
}
//3.出栈/获取栈顶元素
Status Pop(SqStack *S,ElemType *e){
if(S->top==S->base)
return ERROR;
else{
S->top--;
*e=*S->top;
return *e;
}
}
//4判断栈是否为空
Status StackEmpty(SqStack *S){
if(S->top==S->base)
return ERROR;
else
return OK;
}
//5.求栈的长度
Status StackLength(SqStack *S){
if(S->top==S->base)
return ERROR;
else
return (Status)(S->top-S->base);
}
//6.求栈顶元素
Status GetTop(SqStack *S,ElemType *e){ //SqStack *S 和 SqStack S都可以,传地址更节约时间空间
if(S->top==S->base)
return ERROR;
else
*e=*(S->top-1);
return *e;
}
//7.清空栈
Status ClearStack(SqStack *S){
S->top=S->base;
return OK;
}
//8.销毁栈
Status DestroyStack(SqStack *S){
S->top=NULL;
S->stacksize=0;
free(S->base);
return OK;
}
//9.遍历栈/打印栈
Status StackTraverse(SqStack *S){
if(S->base==NULL)
return ERROR;
if(S->top==S->base)
printf("栈中没有元素。。。\n");
ElemType *p;
p=S->top;
while (p>S->base) {
p--;
printf("%d",*p);
}
printf("\n");
return OK;
}
int main(int argc, const char * argv[]) {
SqStack S;
int sele,i,n;
Status a,e;
do {
printf("********************\n");
printf(" 1.构造一个空栈 \n");
printf(" 2.入栈 \n");
printf(" 3.出栈 \n");
printf(" 4判断栈是否为空。 \n");
printf(" 5.求栈的长度 \n");
printf(" 6.求栈顶元素 \n");
printf(" 7.清空栈 \n");
printf(" 8.销毁栈 \n");
printf(" 9.打印栈 \n");
printf(" 0.退出 \n");
printf("********************\n");
printf("请输入你要进行的操作:\n");
scanf("%d",&sele);
switch (sele) {
case 1:
InitStack(&S);
printf("创建成功!\n");
break;
case 2:
printf("请输入栈的长度:\n");
scanf("%d",&n);
for (i=1; i<=n; i++) {
scanf("%d",&e);
Push(&S, e);
}
printf("已全部入栈!\n");
break;
case 3:
printf("出栈元素是:\n");
printf("%d",Pop(&S, &e));
printf("\n");
break;
case 4:
if(StackEmpty(&S))printf("栈不为空!\n");
else printf("栈为空!\n");
break;
case 5:
printf("栈的长度是:\n");
a=StackLength(&S);
printf("%d",a);
printf("\n");
break;
case 6:
printf("栈顶元素是:\n");
e=GetTop(&S, &e);
printf("%d",e);
printf("\n");
break;
case 7:
if (ClearStack(&S)) {
printf("栈已清空!\n");
}else
printf("清空失败!\n");
break;
case 8:
if(DestroyStack(&S)) printf("销毁栈成功!\n");
else printf("销毁栈失败!\n");
break;
case 9:
printf("栈内元素是:\n");
StackTraverse(&S);
break;
default:
sele=0;
exit(0);
break;
}
} while (sele);
}
感悟:
开始写主函数时一直困惑
int main(){
SqStack *S;
InitStack(S);
}
这样子设置结构体类型指针S传给InitStack(),Push(),Pop()等函数不行,后来我明白:SqStack *S只是定义了一个指针,但是这个指针里面的地址内容是空的,也就是说指针没有指向任何东西。把这个指针传给函数时会出错。
为了便于理解,可以设置一个结构体类型的变量,让指针指向此变量,也就是把此变量的地址给指针,然后再给函数传指针就可以通过了。
int main(){
SqStack *S;
SqStack s1;
S=&s1;
InitStack(S);
}
而函数中 InitStack(SqStack *S),Push(SqStack *S,ElemType e)等SqStack *S也是为了设置形参变量来接收结构体变量的地址。
很明显上面主函数里设置指针变量没必要所以直接设置结构体变量,传其地址即可
int main(){
SqStack S;
InitStack(&S);
}
求栈的长度部分
顺序栈栈顶栈底地址相减可以得到栈的长度
开始疑惑为什么不能是 return ((S->top)-(S->base));
这其实是返回栈顶内容与栈底内容相减的结果。