Data structure: implementation of stack (C implementation)

insert image description here

Personal homepage: Personal homepage
Personal column: "Data Structure" "C Language"


foreword

Stack: A special linear structure that only allows insertion and deletion of data at one end. The end that allows manipulation of data is called the top of the stack , and the other end is called the bottom of the stack .
What this blog will implement is an array stack .


1. The implementation idea of ​​the stack

For the particularity of the stack, the time complexity of implementing a stack with an array (insert and delete data at the end of the array) and a linked list (plug and delete data at the head) is O(1), which is not difficult. Advantages and disadvantages
of array stack

  • Arrays support random access (access data with subscripts), and many algorithms require random access support, such as dichotomy...
  • High cache utilization

inferior

  • When the space is not enough, expand the capacity
  • sometimes wastes space

1. Definition of structure

The structure of the stack is very simple
: a pointer to the dynamically opened space, a variable to record the actual space size, and a subscript to record the top element of the stack.

insert image description here

typedef int STDataType;

typedef struct Stack
{
    
    
	STDataType* data;
	int top;//栈顶下标
	int capacity;//空间大小
}Stack;

2. Initialize the stack (StackInit)

The data pointer points to the dynamically opened space, capacity records the size of the space at this time, and top is set to 0.

  • top is set to 0, indicating the position where the top data of the stack will be inserted.
  • top is set to -1, indicating the position of the top data on the stack at this time.

Here, top is set to 0.

insert image description here

//初始化栈

#define SIZE 4

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

	ps->data = (STDataType*)malloc(sizeof(STDataType) * SIZE);
	if (ps->data == NULL)
	{
    
    
		perror("malloc");
		exit(-1);
	}

	ps->top = 0;
	ps->capacity = SIZE;
}

3. Push into the stack (StackPush)

Because top is initialized to 0, you can directly enter data at the subscript of top. But pay attention, check the capacity before entering the data, if top == capacity, you need to expand the capacity.

  • The operation of checking the capacity here can be encapsulated into a function, but it is not necessary, because the operation of the stack only needs to check the capacity when pushing the stack, and other operations do not need to check the capacity. Encapsulating it into a function will reduce the efficiency (the function call needs to Form a function stack frame).

insert image description here

//入栈
void StackPush(Stack* ps, STDataType x)
{
    
    
	assert(ps);

	if (ps->top == ps->capacity)
	{
    
    
		STDataType* tmp = (STDataType*)realloc(ps->data, sizeof(STDataType) * (ps->capacity * 2));
		if (tmp == NULL)
		{
    
    
			perror("realloc");
			exit(-1);
		}

		ps->data = tmp;
		ps->capacity *= 2;
	}

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

4. Pop (StackPop)

top indicates the position where the data on the top of the stack will be pushed into the stack, so to pop the stack, you only need to subtract 1 from top. (The data pushed into the stack will be directly overwritten next time)
But it should be noted that when top = 0, it means that there is no data in the stack, and the stack operation cannot be performed.

  • Pop operation cannot get data

insert image description here

//出栈
void StackPop(Stack* ps)
{
    
    
	assert(ps);
	assert(ps->top != 0);

	ps->top--;
}

5. Get the top element of the stack (StackTop)

top points to the location where the data will be pushed onto the stack, that is, the next location of the top data on the stack.
Then to get the data on the top of the stack, you only need to read top - 1. But it should be noted that if top = 0, then top - 1 = -1 will be accessed out of bounds, so when top = 0, the top element of the stack cannot be obtained.

insert image description here


//获取栈顶元素
STDataType StackTop(Stack* ps)
{
    
    
	assert(ps);
	assert(ps->top > 0);
	
	return ps->data[ps->top - 1];
}

6. Check if the stack is empty (StackEmpty)

top points to the location where the data will be pushed into the stack, and its value also indicates the number of data in the stack.
So we only need to make a judgment of top == 0 to know whether the stack is empty.

//检查栈是否为空
bool StackEmpty(Stack* ps)
{
    
    
	assert(ps);

	return ps->top == 0;
}

7. Destroy the stack (StackDestroy)

Free the dynamically opened space, set capacity to 0 and top to 0.

//销毁栈
void StackDestroy(Stack* ps)
{
    
    
	assert(ps);

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

2. Code implementation

The Stack.h file stores the declaration of the function, the reference of the header file, and the definition of the structure.
The Stack.c file stores the implementation of the function.

//Stack.h  文件

#pragma once

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

#define SIZE 4

typedef int STDataType;

typedef struct Stack
{
    
    
	STDataType* data;
	int top;
	int capacity;
}Stack;


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

//入栈
void StackPush(Stack* ps, STDataType x);

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

//获取栈顶元素
STDataType StackTop(Stack* ps);

//检查栈是否为空
bool StackEmpty(Stack* ps);

//销毁栈
void StackDestroy(Stack* ps);


//Stack.c  文件


#include "Stack.h"

//初始化栈
void StackInit(Stack* ps)
{
    
    
	assert(ps);

	ps->data = (STDataType*)malloc(sizeof(STDataType) * SIZE);
	if (ps->data == NULL)
	{
    
    
		perror("malloc");
		exit(-1);
	}

	ps->top = 0;
	ps->capacity = SIZE;
}


//入栈
void StackPush(Stack* ps, STDataType x)
{
    
    
	assert(ps);

	if (ps->top == ps->capacity)
	{
    
    
		STDataType* tmp = (STDataType*)realloc(ps->data, sizeof(STDataType) * (ps->capacity * 2));
		if (tmp == NULL)
		{
    
    
			perror("realloc");
			exit(-1);
		}

		ps->data = tmp;
		ps->capacity *= 2;
	}

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



//出栈
void StackPop(Stack* ps)
{
    
    
	assert(ps);
	assert(ps->top != 0);

	ps->top--;
}



//获取栈顶元素
STDataType StackTop(Stack* ps)
{
    
    
	assert(ps);
	assert(ps->top > 0);
	
	return ps->data[ps->top - 1];
}


//检查栈是否为空
bool StackEmpty(Stack* ps)
{
    
    
	assert(ps);

	return ps->top == 0;
}



//销毁栈
void StackDestroy(Stack* ps)
{
    
    
	assert(ps);

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

Summarize

The above is my implementation of the stack.
insert image description here

Guess you like

Origin blog.csdn.net/li209779/article/details/132155437