数据结构 &栈和队列(一)

栈和队列是两种非常重要的数据结构。栈是一种先进后出的数据结构,而队列是一种先进先出的数据结构。从它们的特点来看,栈和队列是针锋相对的,但它们却是相互联系的。比如后面要介绍到的“用两个栈实现队列”以及“用队列实现栈”。下面用这幅图再来认识一下栈和队列这两种数据结构的特点。

在这里插入图片描述
接着我们来设计一个栈的结构,并用代码实现入栈、出栈、判栈满、栈空以及获得栈顶元素等。

typedef int ElemType;//类型重定义
#define STACK_INIT 10//初始分配栈空间的大小
#define APPEND_STACK 5//栈满时给栈扩容的大小
typedef struct stack
{
	ElemType *base;//栈底指针
	int top;//记录栈顶
	int stacksize;//当前栈空间大小
}Seqstack,*pSeqstack;

在对栈进行操作的时候首先需要判空,因为对一个空栈进行操作是没有任何意义的,所以判空这一步是必不可少的。

static void DeterPointIsNull(pSeqstack stack)
{
	assert(stack!=NULL);//断言,需要引用头文件#include <assert.h>
	if(stack==NULL)
	{
		printf("stack is null,error!");
		exit(0);
	}
}

由于我们给栈的初始空间分配的大小是固定的,所以当栈存储数据满时,需要对栈进行扩容。

static void AppendSize(pSeqstack stack)
{
	ElemType *s=(ElemType*)malloc(sizeof(ElemType)*
		(APPEND_STACK+stack->stacksize));//开辟一块新的内存
	assert(s!=NULL);//断言这块内存不为空
	for(int i=0;i<stack->stacksize;i++)
	{
		s[i]=stack->base[i];//将栈里面的数据放到新开辟的空间中
	}
	free(stack->base);//释放掉原来的栈空间
	stack->base=s;//让两个指针指向同一块内存
	stack->stacksize+=APPEND_STACK;//栈空间变大
}

接下来我们对栈进行初始化。

void InitSeqstack(pSeqstack stack)
{
	DeterPointIsNull(stack);//判断栈是否为空
	stack->base=(ElemType*)malloc(sizeof(ElemType)*STACK_INIT);
	assert(stack->base!=NULL);
	stack->top=0;
	stack->stacksize=STACK_INIT;
}

除此之外我们还需要对栈里面是否还有元素进行判断。我们有一个栈顶变量top,所以只要判断top的值是否为0,就可以知道栈里面是否还有元素存在。

int EmptyStack(pSeqstack stack)
{
	DeterPointIsNull(stack);
	if(stack->top==0)
	{
		return 1;
	}
	return 0;
}

入栈代码如下:

int Pushstack(pSeqstack stack,ElemType val)
{
	DeterPointIsNull(stack);
	if(stack->top==stack->stacksize)//栈空间不足
	{
		AppendSize(stack);//扩容
	}
	stack->base[stack->top++]=val;
	return 1;
}

获得栈顶元素操作:

int GetTop(pSeqstack stack,ElemType *val)
{
	DeterPointIsNull(stack);
	if(EmptyStack(stack))//如果栈为空
	{
		return 0;//返回0
	}
	*val=stack->base[stack->top-1];//用val返回栈顶元素
	return 1;
}

出栈操作如下:

int PopStack(pSeqstack stack,ElemType *val)
{
	DeterPointIsNull(stack);
	if(!GetTop(stack,val))//如果没有栈顶元素
	{
		return 0;//则不需要出栈
	}
	stack->top--;//栈顶标记--
	return 1;
}

对栈的操作完成以后,我们需要释放栈空间,销毁栈:

void Destroystack(pSeqstack stack)
{
	DeterPointIsNull(stack);
	free(stack->base);
	stack->base=NULL;
	stack->top=stack->stacksize=0;
}

主函数测试:

int main()
{
	Seqstack st;
	int val;
	InitSeqstack(&st);
	for(int i=1;i<=5;i++)
	{
		Pushstack(&st,i);
	}
	for(int i=0;i<st.top;i++)
	{
		printf("%d ",st.base[i]);
	}
	printf("\n");
	PopStack(&st,&val);
	for(int i=0;i<st.top;i++)
	{
		printf("%d ",st.base[i]);
	}
	printf("\n");
	Destroystack(&st);
	for(int i=0;i<st.top;i++)
	{
		printf("%d ",st.base[i]);
	}
	printf("\n");
	return 0;
}

运行结果:
在这里插入图片描述
队列的相关代码见下一篇《数据结构 &栈和队列(二)》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值