高一凡-数据结构第3章-栈与队列

3.1栈

3.1.1栈的数据结构

struct SqStack {
	SElemType *base;//栈底指针
	SElemType *top;//栈顶指针
	int stacksize;//栈的容量,可以看成当前栈可以最大存储多少的元素
};

3.1.2接口

接口功能
void InitStack(SqStack &S)初始化一个栈,主要包含内存的分配
void DestroyStack(SqStack &S)摧毁一个栈,主要包括内存的释放
void ClearStack(SqStack &S)清空一个栈,并不释放内存,而是隐藏和覆盖
Status StackEmpty(SqStack S)判空
int StackLength(SqStack S)返回栈长,元素个数,栈的规模
Status GetTop(SqStack S, SElemType &e)获取栈顶元素
void Push(SqStack &S, SElemType e)压栈
Status Pop(SqStack &S, SElemType &e)弹栈
void StackTraverse(SqStack S, void(*visit)(SElemType))遍历
void print(SElemType e)自定义打印函数,用于传递函数指针

可以清晰的看出,需要对栈进行修改的接口,其形参都是引用形式,而只读形参不带&符号。

3.1.3实现

//1.初始化函数
void InitStack(SqStack &S)
{
	S.base = (SElemType*)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
	//给栈底元素分配一个类似于数组空间的内存,对待base可以看成是数组的起始位置
	//而top可以看成是最后我们插入进去的元素所在数组中的位置(最后一个)
	if (!S.base)//分配不成功,退出
		exit(OVERFLOW);//OVERFLOW宏定义,头文件中定义
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;//宏定义,将栈的规模设置成初始规模
}

//2.销毁一个栈
void DestroyStack(SqStack &S)
{
	free(S.base);//只需要free掉分配给base的内存,所以,我们只对base指针操作
	S.top = S.base = NULL;//指针置零
	S.stacksize = 0;//规模置零
}

//3.清空一个栈
void ClearStack(SqStack &S)
{
	S.top = S.base;//只是将栈顶元素的指针指到了栈底,隐藏了其他元素
}
//4.判空
Status StackEmpty(SqStack S)
{
	return S.top == S.base;//判空,只是简单的判断栈内是否存在元素
	//然而此处的元素只是我们希望用户可见的元素,并不是真正在内存空间中的元素
}
//5.返回栈长
int StackLength(SqStack S)
{
	return S.top - S.base;//返回栈的规模,即当前存了多少元素
}

//6.获取栈顶
Status GetTop(SqStack S, SElemType &e)
{
	if (S.top > S.base)//判空
	{
		e = *(S.top - 1);//解引用的是top-1,这与push操作中的代码有关
		return OK;
	}
	else
	{
		return ERROR;
	}
}
//6.压栈操作
void Push(SqStack &S, SElemType e)
{
//当栈的规模等于栈的容量的时候,我们必须要进行分配空间了
	if (S.top - S.base == S.stacksize)
	{
	//用到的是一个relloc函数,它可以在保存之前内存中元素的基础之上,继续(追加)分配一块空间
		S.base = (SElemType*)realloc(S.base, sizeof(SElemType)*(S.stacksize + STACK_INIT_SIZE));
		if (!S.base)
			exit(OVERFLOW);
		S.top = S.base + S.stacksize;//分配完空间之后,栈底的地址可能已经变化了,所以加上相对的位置,回复原样
		S.stacksize += STACK_INCEEMET;//增加栈的容量
	}
	*(S.top)++ = e;//栈顶永远是*(s.top-1),可以将top看成一个哨兵,防止溢出
}
//7.弹出操作
Status Pop(SqStack &S, SElemType &e)
{
	if (StackEmpty(S))//如果栈为空的话,那么,不能再弹栈了
		return ERROR;
	e = *--S.top;//用了前--,因而栈顶向前移动一位
	return OK;
}
//遍历选项,传入函数指针
void StackTraverse(SqStack S, void(*visit)(SElemType))
{
	while (S.top > S.base)
	{
		visit(*S.base++);
	}
	printf("\n");
}
//简单的函数指针
void print(SElemType e)
{
	printf("%d ", e);
}

VS2015实例代码包:

–未完待续

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值