数据结构-栈的实现

131 阅读3分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

栈的概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。

进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。

栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

image.png

出栈:栈的删除操作叫做出栈。出数据也在栈顶。

image.png


思考:用什么实现栈

image.png


1.0栈的基本结构

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;//指向动态开辟的数组
	int top;
	int capacity;//容量
}ST;

top为-1:

初始化top = -1 先++ 再放数据

top+1才是栈的元素个数

image.png

top为0:

初始化top = 0 先放数据 再++

top标志的就是栈中元素个数

image.png


1.1-栈的初始化

这里我们选择初始化top = 0

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

1.2-栈的销毁

数组是动态开辟的,所以要free,然后把指针置空

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

1.3-入栈

考虑情况:

  • 入栈要考虑是否还有空间:空间不够->扩容

    • 扩容:容量每次扩2倍,使用realloc调整空间大小

    • 最初初始化容量为0,所以要入元素,先给4个大小的空间,指针为空,realloc == malloc

image.png


(初始化top = 0,top标志的是栈顶的下一个元素)

入数据:直接在top位置入,然后top++

void StackPush(ST* ps, STDataType x)
{
	assert(ps);

	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = realloc(ps->a, sizeof(STDataType)*newCapacity);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

1.4-出栈

只需要让top--即可,这样我们就失去了对原来栈顶元素的访问权限了。后序插入数据,就把原来栈顶的数据覆盖了

出栈:要保证栈中还有数据

void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	//assert(ps->top > 0)  //最初初始化top = 0,如果top>0,说明不为空 
    //assert():条件为真,不报错,条件为假:报错
	ps->top--;
}

1.5-得到栈顶元素

top初始化为0:top标志的是栈顶元素的下一个位置 top - 1才是栈顶元素的下标

(若top初始化为-1: top位置就是栈顶元素的下标)

得到栈顶元素:要保证栈中还有数据

STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->a[ps->top - 1];
}

1.6-栈的元素个数

top初始化为0:top的值就是栈中元素个数

top初始化为-1:top+1的值就是栈中元素个数

int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

1.7-栈是否为空

top初始化为0:如果top == 0,说明栈为空

top初始化为-1:如果top == -1,说明栈为空

bool StackEmpty(ST* ps)
{
	assert(ps);

	/*if (ps->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}*/
	return ps->top == 0;
}

1.8-如何后进先出得到所有栈的元素

取栈顶元素->然后出栈->再取栈顶元素.... 直到栈为空

 //如果栈为空,就停止循环
while (!StackEmpty(&st))
{
    printf("%d ", StackTop(&st));//得到栈顶元素
    StackPop(&st);//把栈顶元素退栈
}