代码参照了严蔚敏、吴伟民编写的数据结构(C语言版)。
所有代码采用C语言编写。讲解请查看注释。
- 注1:书中很多函数采用了引用传值,如InitStack(SqStack &S)。但C语言并不支持引用传值,因此统一改为地址传值,即InitStack(SqStack *S)。
头文件及宏定义
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define STACK_INIT_SIZE 100//存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define OK 1
#define Fail 0
#define False 0
#define True 1
#define Error 0
typedef定义数据类型和结构体
typedef int SElemType;
typedef int Status;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;//当前已分配的存储空间,以元素为单位
}SqStack;
InitStack(创建)
Status InitStack(SqStack *S){//构造空栈
S->base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));//分配内存空间,大小为STACK_INIT_SIZE x sizeof(SElemType)
if(!S->base)
exit(OVERFLOW);
S->top=S->base;//栈空
S->stacksize=STACK_INIT_SIZE;
return OK;
}
DestroyStack(销毁)
Status DestroyStack(SqStack *S){//销毁栈
S->base=NULL;
S->top=NULL;
S->stacksize=0;//这些赋值是为了释放内存后再次使用这些内存时不会出错
free(S->base);
return OK;
}
ClearStack(清空)
Status ClearStack(SqStack *S){//清空栈
S->top=S->base;//栈空
}
StackEmpty(判断栈是否为空)
Status StackEmpty(SqStack S){//判断栈是否为空
if(S.base==S.top)
return True;
else
return False;
}
StackLength(获得栈的长度)
int StackLength(SqStack S){//返回栈的长度
return S.top-S.base;
}
GetTop(获得栈顶元素)
Status GetTop(SqStack S,SElemType *e){//若栈不空,用e返回栈顶元素
if(S.base==S.top)
return Error;
S.top--;
*e=*(S.top);
}
Push( 插入)
Status Push(SqStack *S,SElemType e){//插入元素e为新的栈顶元素
if(S->top-S->base>=S->stacksize){//栈满,内存可能溢出
S->base=(SElemType*)realloc(S->base,(STACK_INIT_SIZE+STACKINCREMENT) * sizeof(SElemType));//重新分配内存空间,大小为(STACK_INIT_SIZE+STACKINCREMENT) x sizeof(SElemType)
if(!S->base)
exit(OVERFLOW);
S->top=S->base+S->stacksize;//内存溢出的话S->top将不能正确的指向栈顶,因此重新为其赋值,获得正确的栈顶指针
S->stacksize+=STACKINCREMENT;
}
*S->top=e;
S->top++;
return OK;
}
Pop(删除)
Status Pop(SqStack *S,SElemType *e){//若栈不空,删除栈顶元素并用e返回
if(S->top==S->base)
return Error;
S->top--;
*e=*(S->top);
return OK;
}
StackTraverse(遍历)
首先需要实现Visit()
Status Visit(SqStack S){
while(S.top!=S.base){
S.top--;
printf("%d\n",*S.top);
}
return OK;
}
Status StackTraverse(SqStack S,Status(*visit)()){//遍历
//定义了一个函数指针,函数指针名是visit。它规定指向的函数的返回值必须是Status。
visit(S);
return OK;
}
输入样例
很多函数被我注释掉了,需要使用的话自行取消注释。
int main(void){
SqStack S;
InitStack(&S);
//StackEmpty(S);
int elem1=1;
int elem2=2;
Push(&S,elem1);
Push(&S,elem2);
//StackLength(S);
//int elem3=0;
//GetTop(S,&elem3);
//Pop(&S,&elem3);
//printf("%d\n",elem3);
StackTraverse(S,Visit);//此处相当于*visit=Visit,即将Visit的函数首地址赋给了visit指针,这样在StackTraverse函数内调用visit()就相当于直接调用Visit()
DestroyStack(&S);
}