[Data structure] Detailed explanation of the stack

The content to be shared in this film is stacks and queues, which are a new way of storing data different from linked lists and sequential lists. Let's first understand the contents of stacks

Table of contents

1. Stack

1.1 Graphical understanding of the stack

1.2 The structure of the stack

1.3 Initialize the stack

1.4 Destroy the stack

1.5 push (push)

1.6 pop out

1.7 Get the top element of the stack

1.8 The stack is judged to be empty

1.9 The stack is full

1.10 display stack content


1. Stack

1.1 Graphical understanding of the stack

Stack: A special linear list that only allows insertion and deletion of elements at a fixed end. The 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).

Draw a picture for everyone to observe

        

The above figure has the following two operations 

 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.

It should be better understood with a few examples

As shown in the figure below, if we push the stack with 1, 2, 3, 4, what is the order of popping the stack? 

The order of popping is 4, 3, 2, 1

Of course, the data can be popped out of the stack at any time without requiring the stacking sequence. For example, the stacking sequence here is 1, 2, 3, 4, but the stacking sequence can also be 1, 2, 3, 4. You can set As soon as 1 is pressed in, it will come out, 2 is pressed in and then it will come out, and so on.

Take a look at the question below

若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1

 Obviously the answer is C, because only 1 and 2 are in the stack after 3 is popped out, so we can only get 2 first, then 1, obviously C is wrong

The above is the basic graphic knowledge of the stack, and then we will do some advanced work, or use the addition, deletion, checking and modification of the stack to further deepen our understanding of the stack.

1.2 The structure of the stack

First of all, we still have to start with initialization. In fact, there are two types of stack structures, one is a static stack

typedef int STDataType;
#define N 10
typedef struct Stack
{
STDataType _a[N];
int _top; // 栈顶
}Stack;

Because the capacity of this static structure is hard-coded, it is not convenient for us to add, delete, check and modify operations, so we generally do not use this structure in actual situations, but use the dynamic stack structure

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;//指向栈的开始位置
	int top;
	int capacity;//指向栈的结束位置
}ST;

Then compare and observe through the graph

It can be seen that a points to the beginning of the stack, and capacity points to the end of the stack. What is the meaning of top?

In fact, top has two meanings, it can point to the position of 4 or the position after 4, it depends on how you initialize top;

1.3 Initialize the stack

What is going to be discussed here is how top is initialized to determine the meaning of top

//初始化
void STInit(ST* pst)
{
	assert(pst);
	pst->a = 0;
	pst->top = 0;
	pst->capacity = 0;

}

If we assign the value of top here to 0, then top points to the next position of top

Why does it point to the next element of top?

We can think about it, when we need to add data to the empty stack, when top points to 0, it means that there is already a data

 (top is at 0 position)

 But we are just initializing here, and have not added any elements, so it is contradictory when top points to 0, so in the above example, top points to the next position of 4.

 Of course, if we want top to point to the position of 4, we can assign top to -1, so that the position pointed to by top is at the position of 4 in the above example

In this way, top points to the position of -1. In the above example, it can be indicated that top points to the position of 4. At this time, the initialization method must be understood in the stack initialization.

1.4 Destroy the stack

Destroying the stack is a very simple operation. We only need to free the space in the stack and let the data in it be the same as initialization.

code show as below

//销毁
void Destory(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}

should not be difficult to understand

1.5 push (push)

Different from the linked list and sequence table, the stack cannot be inserted and deleted in two directions. From the above text and illustrations, we know that the stack has only one exit and one entry, so pushing the stack can only be at the top of the stack.

Put the code directly

//添加
void STPush(ST* pst, STDataType x)
{
	if (pst->top = pst->capacity)//判断栈顶是否已经达到了容量的最大值
	{
        
        //创建新的容量,如果容量为0,则开辟四个空间的容量;如果不为0,就开辟原先容量的2倍;
        //注意这里只是对容量的计数
		int newCapacity = pst->capacity = 0 ? 4 : pst->capacity * 2;

        //真正的使用realloc开辟数组的空间
	    STDataType* tmp= (STDataType*)realloc(pst->a, newCapacity * sizeof(pst->capacity));
		if (tmp = NULL)
		{
			return;
		}

		pst->a = tmp;//将新的容量代替掉旧的容量
		pst->capacity = newCapacity;
	}
    //如果栈顶没有达到最大值就赋值给a当前的位置
	pst -> a[pst->top] = x;
	pst->top++;
}

First, the function has two parameters, one is the insertion position, and the other is the inserted data;

Secondly, you need to judge whether your stack top and capacity are equal. If the stack top and capacity are equal, you need to expand the capacity. After the expansion is completed, don’t forget to replace the old capacity with the new capacity.

If the top of the stack has not reached the maximum capacity, it is directly assigned to the current position of a.

I believe it is not difficult to understand.

1.6 pop out

The stack function is very simple, it is to delete the data in the stack, the code is as follows

void STPop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
	
}

The code and idea are very, very simple, just use top--, but it should be noted that it needs to be judged as empty, and after the content of the array is deleted, it cannot continue to be deleted.

1.7 Get the top element of the stack

Through the structure of the stack, we can know that we access the elements of the stack through the subscript of the element, so we can get the element at the top of the stack through the function, the code is as follows

STDataType STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	return pst->a[pst->top - 1];
}

The code and ideas are equally simple. The first thing to pay attention to is the function type. Accessing the top element of the stack must be the type we have typedefed before;

The second is to judge empty. If it is empty, use assert to make a violent assertion to make him report an error;

If it is not empty, return the data at the top-1 position of a (note: because top is the next position of the top element of the stack, top-1 can only be accessed).

1.8 The stack is judged to be empty

Using assert assertion to judge whether the pointer content is empty is a very effective method, and you can know where the error is at a glance

bool STEmpty(ST* pst)
{
	assert(pst);
	if (pst->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

 Here it is judged whether the position pointed to by top can allow a to access the subscript,

If the top element of the stack is 0, return true (true is 1), indicating that the access is valid.

If it is other values, it returns false (false is 0), and the accessed subscript is invalid;

1.9 The stack is full

Very very simple, since top means the next element at the top of the stack, we can directly operate top to complete the count

bool STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

1.10 display stack content

It should be noted here that the stack cannot write a printing function such as Printf to display the contents of the stack like a linked list and a sequence table, but is similar to the situation of displaying while popping the stack.

Test it directly in the main function here

#include"Stack.h"
int main()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	while (!STEmpty(&st))
	{
		printf("%d ", STTop(&st));
		STPop(&st);
	}
	Destory(&st);
	return 0;
}	

First create a variable with the structure of the stack, then initialize it, and then use the push function to push the data onto the stack.

However, when we need to access the data in the stack, we need to access the data fixed by the stack by just getting the top element of the stack, and then use the pop function to pop it out, thus completing the access to the top element of the stack and popping it out of the stack;

Then through the while loop to access and pop the stack multiple times, the operation of accessing all elements in the stack is completed.

The above is the content about the stack that I want to share in this article. If it is helpful to you, please also support Sanlian. Thank you for reading

Guess you like

Origin blog.csdn.net/wangduduniubi/article/details/130727524