Basic data structure - stack (implemented in c language)

Posted by jodyanne on Fri, 03 Sep 2021 04:15:14 +0200

Basic data structure - stack

Stack is a last in, first out linear table. It is the most basic data structure and has applications in many places.

What is stack

Stack is a linear table that restricts insertion and deletion to only one location. Among them, the end that allows insertion and deletion is located at the end of the table, which is called the top of the stack, and the other end that does not allow insertion and deletion is called the bottom of the stack. The basic operations on the stack include PUSH (pressing the stack) and POP (out of the stack). The former is equivalent to the table insertion operation (inserting an element into the top of the stack), and the latter is the deletion operation (deleting an element at the top of the stack). Stack is a last in first out (LIFO) data structure. The first element to be deleted is the nearest stack element. The stack is like a box. Putting a small box into it is equivalent to pressing the stack. Taking a small box out of the stack is the out of stack operation. When taking the box, the last box put in will be taken out first, and the first box put in will be taken out last, which is last in first out. The following is a schematic diagram of a stack:

Implementation of stack

The stack is basically a linear table, so the stack can be realized by creating various tables.

Linked list implementation

Use single linked list to realize stack. The PUSH of the stack is realized through the header insertion method, and the POP of the stack is realized by deleting the elements at the top of the table. The stack realized by this linked list is also called dynamic stack. The physical storage between elements can be discontinuous. The dynamic stack can only PUSH and POP at the top of the stack, and can no longer operate at the end of the stack and in the stack.

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

typedef struct stack {
    int data;
    struct stack *next;
} *Stack;

//Create a new empty stack
Stack createStack() {
    Stack new = (Stack *) malloc(sizeof(Stack));
    if (new == NULL)
        printf("allocation failed");
    new->next = NULL;
    return new;
}
//Determine whether the stack is empty
bool Stack_is_empty(Stack s){
    if(s->next==NULL)
        return 1;
    else
        return 0;
}

//Execute PUSH operation
void push(Stack s, int data) {
    Stack new = (Stack *) malloc(sizeof(Stack));
    new->data = data;
    new->next = s->next;
    s->next = new;
}
//Perform pop operation
void pop(Stack s) {
    Stack Head;
    //Only one stack exit is performed here
    Head = s->next;
    s->next=Head->next;
    printf("%d",Head->data);
    free(Head);
}
//View stack top element
void Stack_top(Stack s){
    if(Stack_is_empty(s)){
        printf("Empty stack");
    } else{
        printf("%d",s->next->data);
    }
}
int main() {
    Stack s;
    s = createStack();
    if(Stack_is_empty(s)){
        printf("Empty stack");
    } else{
        printf("Not an empty stack");
    }
    push(s,3);
    push(s,4);
    Stack_top(s);
    if(Stack_is_empty(s)){
        printf("Empty stack");
    } else{
        printf("Not an empty stack");
    }
    pop(s);
    if(Stack_is_empty(s)){
        printf("Empty stack");
    } else{
        printf("Not an empty stack");
    }
    return 0;
}

Array implementation

Stack is implemented by array, which is also called static stack. Use a subscript to record the position of the elements in the stack. The subscript of the empty stack is - 1. PUSH a number each time, increase the subscript value by 1, and directly reduce the subscript by 1 during POP (the elements in the array can be overwritten next time). It should be noted that POP operation and PUSH subscript out of bounds on empty stack are abnormal.

#include <stdio.h>
#include <malloc.h>

/**
 * index Subscript at top of stack
 * capacity Stack capacity
 * int *array Stack array
 */
typedef struct {
    int index;
    int capacity;
    //The statement that the array name is equal to the pointer can also be allocated directly
    int *array;
} *stack_array;
//Stack initialization
stack_array init(int num){
    stack_array s=(stack_array*)malloc(sizeof(stack_array));
    s->array=(int *) malloc(sizeof(stack_array)*num);
    s->capacity=num;
    s->index=-1;
    return s;
}
void PUSH(stack_array s,int data){
    s->index++;
    s->array[s->index]=data;
}
void pop(stack_array s){
    printf("%d\n",s->array[s->index]);
    s->index--;
}
void stack_top(stack_array s){
    printf("%d\n",s->array[s->index]);
}
void stack_is_empty(stack_array s){
    if(s->index<0)
        printf("Stack empty\n");
    else
        printf("Not an empty stack\n");
}
int main() {
    stack_array s;
    s=init(4);
    stack_is_empty(s);
    PUSH(s,3);
    PUSH(s,5);
    PUSH(s,32);
    pop(s);
    pop(s);
    stack_top(s);
}

Advantages and disadvantages of linked list implementation and array implementation of stack

Using linked list dynamic implementation can not worry about memory allocation, but malloc and free function calls are expensive
The array size needs to be declared in advance when using the array implementation. The application may be too large, resulting in memory waste, or the application may be too small, resulting in subscript out of bounds
In addition to the above problems, the execution efficiency of array implementation is higher than that of linked list implementation

reference material

Dahua data structure
Fundamentals of data structure and algorithm (Qingdao University - Wang Zhuo)

Topics: C data structure stack