栈的实现(数组栈)

目录

一、前言

二、什么是栈?

三、栈各个接口的实现

1、栈元素的结构定义

2、栈的初始化

2、栈元素的插入(入栈)

3、出栈

4、栈的销毁

5、返回栈顶元素

6、返回栈元素个数

 7、判断栈是否为空

三、结言


一、前言

本篇文章涉及顺序表的相关知识,如有不知何为顺序表的童鞋,请自行翻阅上篇博客---线性表之顺序表

二、什么是栈?

:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO (Last ln First Qut)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。

 由下图理解什么叫做后进先出原则

 栈的实现(数组栈)_第1张图片

三、栈各个接口的实现

为了方便大家理解和测试代码,在这里我先给出各个接口的测试代码。

void test1()
{
	ST p;
	StackInit(&p);
	StackPush(&p, 1);
	StackPush(&p, 2);
	printf("%d ", StackTop(&p));
	StackPop(&p);
	StackPush(&p, 3);
	StackPush(&p, 4);
	while(!StackEmpty(&p))
	{
		printf("%d ", StackTop(&p));
		StackPop(&p);
	}
	StackDestroy(&p);

}


int main()
{
	test1();
	return 0;
}

1、栈元素的结构定义

typedef int SDataType;

typedef struct stack
{
	SDataType* a;   //这里的栈是使用动态开辟的数组
	int top;        //代表栈顶
	int capacity;   //栈的容量
}ST;

2、栈的初始化

初始化栈较简单,我们只需要让指针a指向NULL,topcapacity等于0。

void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

2、栈元素的插入(入栈)

我们让数组的首部作为栈顶尾部作为栈顶,栈是后进先出的,所以我们插入元素时(即入栈),只需要在数组的尾部插入;删除元素时(即出栈),只需要让top-1;这样做就满足了栈的定义。

void StackPush(ST* ps, SDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
	
		SDataType* temp = realloc(ps->a, sizeof(SDataType) * NewCapacity);
		if (temp == NULL)
		{
			printf("realloc fail.\n");
			exit(-1);
		}
		ps->a = temp;
		ps->capacity = NewCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

top==capacity时,说明需要扩容,扩容的两种情况,当capacity为0时,什么栈一个元素也没有,这个时候我们就分配4个空间给指针a,如果capacity!=0,我们就让capacity*2,让指针a指向的空间扩大2倍

3、出栈

出栈时,我们要保证有元素可以出栈,因此我们使用了assert(ps->top>0)。

void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

4、栈的销毁

我们需要让指针a的空间释放,然后将top和capacity赋值为0。

void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = 0;//没有写
	ps->capacity =0;//没有写
}

5、返回栈顶元素

栈顶元素的下标为top-1,因此我们只需要返回该下标的元素就行;同时我们要保证栈是有元素的。

SDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return (ps->a[ps->top - 1]);
}

6、返回栈元素个数

top的数值为几,则栈就有多少个元素,因此我们只需要返回top的数值。

int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

 7、判断栈是否为空

我们只需要判断top是否等于0。

bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

三、结言

本篇博客中,我们用的是数组完成栈的操作,是顺序表的延伸使用,所以大家主要理解顺序表是如何实现的,顺序表具体实现请看我的上篇博客。当然,我们也可以使用链表来完成栈的操作,但是链表栈对于数组栈是没有优势的(具体原因我会在以后的关于链表的博客说明),因此我们通常使用数组来完成栈的操作。

你可能感兴趣的:(笔记,数据结构)