C语言 数据结构顺序栈的基本操作(附输入样例和讲解)

代码参照了严蔚敏、吴伟民编写的数据结构(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);
}

输出结果

输出结果

  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值