<Data structure> Implementation of stack

content

foreword

       stack concept

       stack structure

Implementation of stack

       Create stack structure

       initialize stack

       destroy stack

       push onto the stack

       pop

       Get the top element of the stack

       Get the number of valid elements in the stack

       Check if stack is empty

total code

       Stack.h file

       Stack.c file

       Test.c file


foreword

stack concept

  • Stack: A special linear list that allows insertion and removal of elements only at one fixed end. One end where data insertion and deletion 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 LIFO (Last In First Out) principle. Kind of like a pistol magazine, the last loaded bullet is always fired first, unless the gun is broken.
  • Push stack: The insertion operation of the stack is called push/push/push. (Incoming data is at the top of the stack)
  • Pop: The deletion of the stack is called pop. (The output data is also on the top of the stack)

Notice:

1. Function calls also have stacks. Is there any difference between these two stacks?

Of course there are differences. The function call will call the stack frame, and there is also a stack in the memory. When the program runs, the function needs to be executed. The local variables, parameters, return values, etc. in the function must be stored in the function stack frame.

The two stacks have nothing to do with each other, one is the stack in the data structure. The other is an area of ​​memory divided in the operating system, called the stack, which is used to create a stack frame when a function is called. Although there is no connection in nature, they all conform to the last-in, first-out rule.

2. Suppose the stacking sequence is: 1 2 3 4, then the pop-out sequence must be: 4 3 2 1?

of course not. Although the rules are clearly LIFO, this is relatively speaking. If it is said that each time it enters one and then one is released, and then continues to push the stack, doesn't it also conform to the last-in-first-out rule? Just like the above example, it is not surprising that you say that the stacking order is 1 2 3 4. Each time you enter one, one goes out and one goes in, which also conforms to the rules. It is also possible to push two into the stack and then go in and out again, such as 2 1 4 3.

stack structure

Implementation of stack

Create stack structure

  • Stack.h file:
//创建栈结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* a; //存储数据
	int top; //栈顶的位置
	int capacity; //容量
}ST;

initialize stack

  • Thought:

The initialization is relatively simple. After learning the previous sequence table, it is very easy to initialize the stack

  • Stack.h file:
//初始化栈
void StackInit(ST* ps);
  • Stack.c file:
//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}
  • Notice:

​​​It is intentional to set top to 0 when initializing here. First of all, it has been marked when the stack structure was created above. top is used to record the position of the top of the stack. Since it is the position of the top of the stack, when top is initialized to 0, we can directly put the data into the stack, and then top++ , but when top is initialized to -1, top needs ++ to put data first, because data cannot be put in a position where a negative number does not belong to the stack. The following figure demonstrates the process:

 This article uses top = 0 as an example

destroy stack

  • Thought:

The dynamically opened memory space must be released, free can be set to empty, and the rest of the data is set to 0.

  • Stack.h file:
//销毁栈
void StackDestory(ST* ps);
  • Stack.c file:
//销毁栈
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

push onto the stack

  • Ideas:

The previous article has emphasized that top is initialized to 0, so it should be pushed directly into the data, and top++, but before that, it is necessary to judge whether the space is enough. When top=capacity, the stack is full, then realloc needs to be expanded.

  • Stack.h file:
//压栈
void StackPush(ST* ps, STDataType x);
  • Stack.c file:
//压栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//如果栈满了,考虑扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量
		ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (ps->a == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->capacity = newcapacity; //更新容量
	}
	ps->a[ps->top] = x;//将数据压进去
	ps->top++;//栈顶上移
}

pop

  • Ideas:

Before you pop the stack, make sure that top is not empty, and the condition for top not to be empty is top>0, so you must also assert that top>0, and then directly move the top of the stack down -- that's it. Similar to the idea of ​​a sequence table.

  • Stack.h file:
//出栈
void StackPop(ST* ps);
  • Stack.c file:
//出栈
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

Get the top element of the stack

  • Ideas:

First of all, we must figure out who is the top element of the stack, is it the top position or the top-1 position? Obviously, the top-1 position is the top element of the stack, because it was clearly pointed out that top was 0 during the initialization above, and the data was directly put into the stack when it was pushed. At this time, the first data subscript is 0, and then + +top and then push other data, it can be seen that the top element of the stack is the position of the subscript top-1.

  • Stack.h file:
//访问栈顶数据
STDataType StackTop(ST* ps);
  • Stack.c file:
//访问栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素
}

Get the number of valid elements in the stack

  • Thought:

As mentioned above, the subscript top-1 is the top element of the stack, so does it mean that there are top-1 elements in total? Of course not, here is the same idea as the array subscript, the number of elements should be the top, just return it directly.

  • Stack.h file:
//有效元素个数
int StackSize(ST* ps);
  • Stack.c file:
//有效元素个数
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

Check if stack is empty

  • Ideas:

When the value of top is 0, it is empty, and return can be returned directly.

  • Stack.h file:
//判空
bool StackEmpty(ST* ps);
  • Stack.c file:
//判空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0; //如果top为0,那么就为真,即返回
}
  • Test.c file:
void TestStack()
{
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	while (!StackEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
	StackDestory(&st);
}
  • The effect is as follows:

total code

Stack.h file

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

//创建栈结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* a; //存储数据
	int top; //栈顶的位置
	int capacity; //容量
}ST;

//初始化栈
void StackInit(ST* ps);

//销毁栈
void StackDestory(ST* ps);

//压栈
void StackPush(ST* ps, STDataType x);

//出栈
void StackPop(ST* ps);

//判空
bool StackEmpty(ST* ps);

//访问栈顶数据
STDataType StackTop(ST* ps);

//有效元素个数
int StackSize(ST* ps);

Stack.c file

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

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

//压栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//如果栈满了,考虑扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量
		ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (ps->a == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->capacity = newcapacity; //更新容量
	}
	ps->a[ps->top] = x;//将数据压进去
	ps->top++;//栈顶上移
}
//出栈
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

//判空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0; //如果top为0,那么就为真,即返回
}

//访问栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素
}

//有效元素个数
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

Test.c file

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void TestStack()
{
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	while (!StackEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
	StackDestory(&st);
}
int main()
{
	TestStack();
	return 0;
}

Guess you like

Origin blog.csdn.net/bit_zyx/article/details/123763458