The strongest data structure in history----Two simulation implementations of easily handling the stack

1. Concept and structure of stack

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.

Push stack: The insertion operation of the stack is called push/push/push, and the pushed 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 .

image-20220325202945680

Note: Does the stack in the data structure have anything to do with the stack in our C language?

The former is a data structure used to store data. The latter 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.

Q: When the stacking sequence is 1 2 3 4, does the stacking sequence have to be 4 3 2 1?

Answer: Not necessarily, because it is possible that 1 is pushed into the stack and then popped off the stack. The same is true for 2, 3, and 4. At this time, the stacking sequence is 1 2 3 4. In fact, there are many ways to pop the stack, and LIFO is relative.

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 implementation of an array is better. Because the cost of inserting data at the end of the array is relatively small.

image-20220325195054807

The code implementation of the stack:

2.1 Implementation of Array Stack

The first: the implementation of the array stack (recommended)

image-20220326154549746

Stack.h file code:

#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);
int SizeStack(ST* ps);
STDataType StackTop(ST* ps);

Stack.c file code:

#include"Stack.h"
void StackInit(ST* ps)//栈的初始化
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 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 ? 2 : 2 * ps->capacity;
		STDataType*new = (STDataType*)realloc(ps->a,sizeof(STDataType)*newCapacity);
		if (new == NULL)
		{
			printf("fail malloc\n");
			exit(-1);
		}
		ps->a = new;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top++] = x;
}
void StackPop(ST* ps)//出栈
{
	assert(ps);
	assert(ps->top > 0);
	--ps->top;
}
bool StackEmpty(ST* ps)//判断栈是否为空
{
	assert(ps);
	return ps->top == 0;
}
STDataType StackTop(ST* ps)//取栈顶元素
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}
int SizeStack(ST* ps)//求栈的元素数量
{
	assert(ps);
	return ps->top;
}

2.2 Implementation of linked list stack

The second: the implementation of linked list stack
image-20220329124520653

The implementation of the linked list stack here uses a singly linked list (with a sentinel bit) as a carrier, and the position of the stack is taken from the head of the singly linked list, that is, the position behind the sentinel bit, and what is popped out of the stack is also behind the sentinel bit. node.

Stack.h file code:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int STDataType;
typedef struct StackNode
{
	STDataType val;
	struct StackNode* next;
}StackNode;
StackNode* StackInit();
void StackDestory(StackNode* ps);
void StackPush(StackNode* ps,STDataType x);
void StackPop(StackNode* ps);
bool StackEmpty(StackNode* ps);
int SizeStack(StackNode* ps);
STDataType StackTop(StackNode* ps);
StackNode* BuyStackNode(STDataType x);

Stack.c file code:

#include"Stack.h"
StackNode* BuyStackNode(STDataType x)//开辟一个栈(链表的)节点
{
	StackNode* newnode = (StackNode*)malloc(sizeof(StackNode));
	if (newnode == NULL)
	{
		printf("fail malloc\n");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->val = x;
	return newnode;
}
StackNode* StackInit()//栈的初始化
{
	StackNode* head = BuyStackNode(-1);
	return head;
}
void StackDestory(StackNode* ps)//栈的销毁
{
	assert(ps);
	StackNode* cur = ps;
	while (cur)
	{
		StackNode* next = cur->next;
		free(cur);
		cur = next;
	}
}
void StackPush(StackNode* ps, STDataType x)//入栈
{
	assert(ps);
	StackNode* newnode = BuyStackNode(x);
	StackNode* next = ps->next;
	ps->next = newnode;
	newnode->next = next;
}
void StackPop(StackNode* ps)//出栈
{
	assert(ps);
	assert(ps->next);
	StackNode* pop = ps->next;
	ps->next = pop->next;
	free(pop);
}
bool StackEmpty(StackNode* ps)//判断栈是否为空
{
	assert(ps);
	return ps->next == NULL;
}
int SizeStack(StackNode* ps)//求栈中有的节点的数目
{
	assert(ps);
	int size = 0;
	StackNode* cur = ps->next;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}
STDataType StackTop(StackNode* ps)//求栈顶的节点存储的元素
{
	assert(ps);
	assert(ps->next);
	return ps->next->val;
}

Guess you like

Origin blog.csdn.net/m0_57304511/article/details/123818499