1. Concept and structure of stack
Stack: A special linear list that only allows insertion and deletion of elements at a fixed end. One end of the stack 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 LIFO (Last In First Out) principle. Push on the stack: The insertion operation of the stack is called push/push/push, The input data is on the top of the stack. Pop: The deletion operation of the stack is called popping. The output data is also on the top of the stack.
2. Implementation of stack
The implementation of stack can generally be implemented usingarray or linked list. Relatively speaking, array structure implementation is better. Because the cost of inserting data at the end of the array is relatively small.
2.1 Define a dynamic stack
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
2.2 Stack initialization
void STInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
2.3 Destruction of stack
void STDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
2.4 Pushing data onto the stack
When data is pushed into the stack, you must first consider whether it needs to be expanded, so first determine whether top is equal to capacity. If it is full, then determine whether capacity is expanded for the first time. If so, expand it to 4. If not, If it is, expand it by 2 times, and then expand the space. Here cleverly uses the realloc library function, because if the space that needs to be expanded is 0, it is equivalent to malloc< a i=2>, after the expansion is completed, put the data into the top position, and then top++, so that top will always be the next position of the top element of the stack.
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4:ps->capacity * 2;
STDataType* tmp = (STDataType*) realloc(ps->a, sizeof(STDataType) * newCapacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
2.5 Data popping
First make sure that the stack is not empty, and only data can be output from top>0. Just pop the stack and go directly to top--.
void STPop(ST* ps, STDataType x)
{
assert(ps);
//空
assert(ps->top > 0);
--ps->top;
}
2.6 Number of data in the stack
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
2.7 Determine whether the stack is empty
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
2.8 Get the top element of the stack
It should be noted here that the position of the top element of the stack is top-1.
STDataType STTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
Complete code
Stack.h:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* ps);
void STDestroy(ST* ps);
void STPush(ST* ps,STDataType x);
void STPop(ST* ps);
int STSize(ST* ps);
bool STEmpty(ST* ps);
STDataType STTop(ST* ps);
Stack.c:
void STInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void STDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4:ps->capacity * 2;
STDataType* tmp = (STDataType*) realloc(ps->a, sizeof(STDataType) * newCapacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void STPop(ST* ps, STDataType x)
{
assert(ps);
//空
assert(ps->top > 0);
--ps->top;
}
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
STDataType STTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}