0
点赞
收藏
分享

微信扫一扫

基于C语言的栈实现

->Gitee源码点击这里<-
之前所实现的顺序表和链表都成为线性表,即他们的从逻辑上来看是连续的,线性的,按顺序的。
栈是一种特殊的线性表,其实现要基于顺序表或者链表,相比之下用顺序表来实现更优;
而和顺序表区别在于,栈不支持随机位置的数据插入和删除,入栈的数据遵循后进先出的原则。
栈的逻辑结构示意图:
在这里插入图片描述

接下来我们使用顺序表来实现一个栈。

首先定义一个结构体,该结构体包含了栈的相关信息:

typedef int STDatatype;
typedef struct Stack
{
	STDatatype* a; //指向动态开辟的栈
	int top = 0; //栈顶
	int capacity = 0;//栈容量
};

接着对栈进行初始化

void StackInit(Stack* pst)
{
	pst->a = (STDatatype*)malloc(sizeof(STDatatype) * 4);//给定栈的初始大小
	if (pst->a == NULL)
	{
		printf("Init Failed\n");
		exit(-1);
	}
	pst->top = 0;
	pst->capacity = 4;
}

栈在处理数据时,只需要两个接口即可,即入栈接口和出栈接口。入栈接口的本质就是顺序表的尾插;出栈接口的本质就是顺序表的尾删
一、入栈接口

void StackPush(Stack* pst, STDatatype data)
{
	assert(pst);
	//查询栈是否已满
	if (pst->top == pst->capacity)
	{
		Stack* newa = (STDatatype*)realloc(pst->a, sizeof(STDatatype) * pst->capacity * 2);
		if (newa == NULL)
		{
			printf("realloc failed\n");
			exit(-1);
		}
		pst->a = newa;
		pst->capacity *= 2;
	}
	pst->a[pst->top] = data;
	pst->top++;
}

二、出栈接口
这里要注意,栈为空时,出栈接口不希望被调用
所以我们先设计一个判断栈是否为空的接口

bool StackIsEmpty(Stack* pst)
{
	assert(pst);
	return pst->top == NULL;
}

接着在出栈接口中,借助判空接口添加断言

void StackPop(Stack* pst)
{
	assert(pst);
	assert(!StackIsEmpty(pst)); //调用删除接口栈不能为空
	pst->top--;
}

三、获取栈顶元素

STDatatype StackTop(Stack* pst)
{
	assert(pst);
	assert(!StackIsEmpty(pst));
	return pst->a[pst->top - 1];
}

四、栈中有效元素的个数

int StackSize(Stack* pst)
{
	assert(pst);
	return pst->top;
}

五、栈的销毁
不要忘记,栈时动态开辟的,使用完毕要销毁空间

void StackDestroy(Stack* pst)
{
	free(pst->a);
	pst->capacity = 0;
	pst->top = 0;
}

对于栈的一些说明:
对于栈,不设计打印接口,若想通过打印来看到栈中数据,需要使用StackTop()获取栈顶元素接口和StackPop()出栈接口,获取栈顶元素,打印,然后删除该栈顶元素,如此循环,当所有元素被打印时,栈已经为空了:

//栈中已经依次入栈1,2,3,4
//打印栈中元素
int main()
{
	Stack mystack;
	StackInit(&mystack);
    while (!StackIsEmpty(&mystack))
	{
		printf("%d ", StackTop(&mystack));
		StackPop(&mystack);
	}
	StackDestroy(&mystack);
}
举报

相关推荐

0 条评论