[Data structure -- C language] Stack (Stack)

Table of contents

1. stack

1.1 The concept and structure of the stack

2. Implementation of the stack

2.1 Interface

3. Implementation of the interface

3.1 Initialization

3.2 Push/Push

3.3 Popping

3.4 Get the top element of the stack

3.5 Get the number of effective elements in the stack

3.6.1 bool type interface

3.6.2 int type interface

3.7 Destroying the stack

4. Complete code

5. Function test


1. stack

1.1 The concept and structure of the stack

Stack: A special linear list that only allows insertion and deletion of elements at a fixed end. One end where data insertion and deletion operations are performed
is called the top of the stack, and the other end is called the bottom of the stack.
The data elements in the stack follow the principle of LIFO (Last In First Out).

Push stack: The insertion operation of the stack is called push/push/push, and the incoming data is at the top of the stack .
Popping: The deletion operation of the stack is called popping. The output data is also on the top of the stack .

Let's understand the stack with things in life: candied haws

When stringing candied haws, the last candied haws goes in first, but the first one we eat is the last one.

2. Implementation of the stack

The implementation of the stack can generally be implemented using an array or a linked list . Relatively speaking, the structure of the array is better. Because the cost of inserting data at the end of the array
is relatively small. In this article, we use arrays to implement stacks.


2.1 Interface

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶
	int capacity;  // 容量 
}Stack;
// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

3. Implementation of the interface

3.1 Initialization

Our stack starts out empty, so the capacity and top of the stack are assigned 0.

We can also assign the top of the stack to -1. When pushing the stack, first let the top pointer ++, and then push the element onto the stack, so that the top pointer of the stack just points to the top element of the stack. But here we still assign the top pointer of the stack to 0, so that there is no need to operate when obtaining valid elements in the stack, which provides convenience for later.

void StackInit(Stack* ps)
{
	assert(ps);

	ps->a = NULL;
	//ps->top = -1;//top 指栈顶数据
	ps->top = 0;//top 指栈顶数据的下一个位置
	ps->capacity = 0;
}

3.2 Push/Push

Before pushing into the stack, we must first determine whether the stack is full, and if it is full, we will expand the advanced nature of the stack. We did not start malloc space first, but used realloc for the first time. There is a trick here, that is to use the ternary operator to check whether the capacity is 0. If it is 0, it means that it is the first time to open space, assign a value of 4 to newcapacity, if it is not 0, it means expansion, then expand the new capacity to twice the previous capacity.

After the judgment is full, we will push it into the stack. This is actually to put elements into the array, put an element into the top position of the stack, and let ps->top++ take a step back.

void StackPush(Stack* ps, STDataType data)
{
	assert(ps);

	if (ps->capacity == ps->top)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail:");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}

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

3.3 Popping

Popping out of the stack is very simple, just let ps->top--, the next element pushed into the stack will overwrite the previous element.

void StackPop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	ps->top--;
}

3.4 Get the top element of the stack

Before obtaining the top element of the stack, it needs to be judged as empty. If it is empty, there is no stack top pointer. The top element of the stack is the element whose subscript is top-1, so returning ps->[ps->top-1] is the top element of the stack.

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

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

3.5 Get the number of effective elements in the stack

Since the subscript top is the next position of the top element of the stack, the return top is the number of valid elements in the stack.

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

	return ps->top;
}

3.6.1 bool type interface

int StackEmpty(Stack* ps)
{
	assert(ps);

	return ps->top == 0;
}

3.6.2 int type interface

Here we agree to return non-zero if it is empty, and return 0 if it is not empty.

int StackEmpty(Stack* ps)
{
	assert(ps);

	if (0 == ps->top)
		return 1;
	else
		return 0;
}

3.7 Destroying the stack

Release the array and make it empty, and assign the capacity and the top of the stack to 0.

void StackDestroy(Stack* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

4. Complete code

The complete code is in the code warehouse, the entry: C language: C language learning code, review more - Gitee.com

5. Function test

Guess you like

Origin blog.csdn.net/Ljy_cx_21_4_3/article/details/130734426