The interviewer asked me what a "stack" is, and I drew 10 pictures to explain

Follow, star public account, direct access to exciting content

ID: Technology makes dreams greater

Author: Li Xiao Yao

Stack concept

The stack is a data structure that is limited to only operate on one end of the table, and the stack is a first-in-last-out data structure. The end that allows operation is called the top of the stack , and the one that is not allowed is called the bottom of the stack , as shown in the following figure Show:

Before we talked about the linked list, we can only operate on the end node of its linked list, and only insert a new node and delete the last node, and such a restrictive'linked list' ' , Is what we call the stack .

Just like a dead end, there is only one exit, as shown in the figure, there is a concept:

Node design of the stack

The stack is divided into an array stack and a linked list stack . The differences are as follows:

  • 数组栈Use arrays to simulate functions, which is faster and more convenient;

  • 链表栈Designing with the idea of ​​linked list is relatively troublesome to implement, but it is stable and not easy to make mistakes;

The linked list stack is divided into static linked list stack and dynamic linked list stack . The difference is as follows:

  • 静态链表栈The space size of a given stack is not allowed to exceed the storage of elements exceeding the given data size;

  • 动态栈It is created using the method of automatically creating space. As long as it meets the hardware requirements of the machine and the control of the compiler, it is theoretically great.

Array stack

It actually uses a continuous storage space to store the data elements in the stack, which has the following characteristics:

  1. The storage space occupied by the elements must be continuous. The continuity here refers to logical continuity, not physical continuity.

  2. The location of the elements in the storage space is stored in a logical order

Let's take an example. Since the C language array subscripts all start with 0, and the size of the space required for the use of the stack is difficult to estimate, when initializing the empty stack, the maximum capacity of the stack should not be set.

We first set a basic capacity for the stack. During the STACK_ process, when the stack space is not enough, it will gradually expand.

Set two constants, STACK_INIT_SIZE(initialization of storage space allocation) and STACK_INCREMENT(increment of storage space allocation), the macro definition is as follows

#define STACK_INIT_SIZE 1000 //数值可以根据实际情况确定
#define STACK_INCREMENT 10   //数值可以根据实际情况确定

The definition of the stack is as follows

typedef struct      
{
    void *base; 
    void *top;
    int stackSize;
} SqSTACK;
  • base represents the bottom pointer of the stack

  • top represents the top pointer of the stack

  • stackSize represents the maximum capacity currently available for the stack

If the value of base is NULL, it means that the stack structure does not exist; the initial value of top points to the bottom of the stack, that istop = base;

Whenever a new element is inserted, the pointer top is incremented by 1, otherwise it is decremented by 1. The top pointer of the non-empty stack is always above the next pointer of the top element of the stack .

The relationship between the data elements and the pointer on the top of the stack is shown in the following figure:

Linked list stack

We take the dynamic linked list stack of the linked list stack as an example to design the stack.

The first is the node of the stack. Two structures are designed. A structure Node represents the node, which contains a datadomain and nextpointer, as shown in the figure:

Node

Among them, data represents data, and the next pointer represents the next pointer, which points to the next node, and each node is linked through the next pointer.

Next is the focus of our design. For this restrictive design, we need to add an additional structure, which includes a pointer top that always points to the top of the stack and a counter count to record the number of elements.

Its main function is to set the pointers of allowed operation elements and determine when the stack is empty , as shown in the figure:

Stack

Here I use a combination of top and count . The code can be expressed as:

//栈的结点设计
//单个结点设计,数据和下一个指针
typedef struct node     
{
    int data; 
    struct node *next;
} Node;

Use the above nodes to create a stack, which is divided into a top pointer to the head node and count for counting

typedef struct stack    
{
    Node *top;
    int count;
} Link_Stack;

The basic operation of the stack-into the stack (push the stack)

The basic sequence of stacking can be shown in the following figure:

When the stack (push) operation, we just need to find space for top points to create a new node, the next pointer to the new node points to top the pointer to the space , and then the top pointer transfer, and point to the new Node, this is the push operation .

The code can be expressed as:


//入栈 push
Link_Stack *Push_stack(Link_Stack *p, int elem)
{
    if (p == NULL)
        return NULL;
    Node *temp;
    temp=(Node*)malloc(sizeof(Node));
    //temp = new Node;
    temp->data = elem;
    temp->next = p->top;
    p->top = temp;
    p->count++;
    return p;
}

The basic operation of the stack-pop

The pop operation is an operation that repeats when the stack is not empty. You must perform a null operation , delete the element at the top of the stack, and move the top pointer and next down.

The code can be expressed as:

//出栈 pop
Link_Stack *Pop_stack(Link_Stack *p)
{
    Node *temp;
    temp = p->top;
    if (p->top == NULL)
    {
        printf("错误:栈为空");
        return p;
    }
    else
    {
        p->top = p->top->next;
        free(temp);
        //delete temp;
        p->count--;
        return p;
    }
}

The basic operation of the stack-traversal

This is very common, and it is also a necessary means for us to debug.

The traversal of the stack is relatively complicated. Due to the special nature of the stack, it only allows operations on one end, so the traversal operations are always in reverse order .

To describe briefly, the process is, when the stack is not empty, access down from the top element of the stack once until the pointer points to an empty (that is, to the end of the stack).

The code can be expressed as:

//遍历栈:输出栈中所有元素
int show_stack(Link_Stack *p)
{
    Node *temp;
    temp = p->top;
    if (p->top == NULL)
    {
        printf("");
        printf("错误:栈为空");
        return 0;
    }
    while (temp != NULL)
    {
        printf("%d\t", temp->data);
        temp = temp->next;
    }
    printf("\n");
    return 0;
}

Code realization of stack array and stack linked list

Finally, we use code to help us understand:

Stack array

The array stack is a faster way to simulate the implementation of the stack, we won't talk about it here.

Simulation means that instead of using a real linked list design, an array is used for simulation operations .

In other words, this is a simulation type operation, which can quickly help us build the code, analyze the process, and the corresponding implementation is more convenient.

The code is as follows:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 10000
 
//结点设计
typedef struct stack{
    int data[maxn];
    int top;
}stack;
 
//创建
stack *init(){
    stack *s=(stack *)malloc(sizeof(stack));
    if(s==NULL){
        printf("分配内存空间失败");
        exit(0);
    }
    memset(s->data,0,sizeof(s->data));
    //memset操作来自于库文件string.h,其表示将整个空间进行初始化
    //不理解可以查阅百度百科https://baike.baidu.com/item/memset/4747579?fr=aladdin
    s->top=0;     //栈的top和bottom均为0(表示为空)
    return s;
}
 
//入栈push
void push(stack *s,int data){
    s->data[s->top]=data;
    s->top++;
}
 
//出栈pop
void pop(stack *s){
    if(s->top!=0){
        s->data[s->top]=0;  //让其回归0模拟表示未初始化即可
        s->top--;
    }
}
 
//模拟打印栈中元素
void print_stack(stack *s){
    for(int n=s->top-1;n>=0;n--){
        printf("%d\t",s->data[n]);
    }
    printf("\n");   //习惯性换行
}
 
int main(){
    stack *s=init();
    int input[5]={11,22,33,44,55};  //模拟五个输入数据
    for(int i=0;i<5;i++){
        push(s,input[i]);
    }
    print_stack(s);
    /
    pop(s);
    print_stack(s);
    return 0;
}

The compilation results are as follows:

Stack list

#include <stdio.h>
#include <stdlib.h>
//栈的结点设计
//单个结点设计,数据和下一个指针
typedef struct node     
{
    int data; 
    struct node *next;
} Node;
//利用上面的结点创建栈,分为指向头结点的top指针和计数用的count
typedef struct stack    
{
    Node *top;
    int count;
} Link_Stack;
 
//创建栈
Link_Stack *Creat_stack()
{
    Link_Stack *p;
    //p = new Link_Stack;
    p=(Link_Stack*)malloc(sizeof(Link_Stack));
    if(p==NULL){
        printf("创建失败,即将退出程序");
        exit(0);
    }
 else
 {printf("创建成功\n");
 }
    p->count = 0;
    p->top = NULL;
    return p;
}
 
//入栈 push
Link_Stack *Push_stack(Link_Stack *p, int elem)
{
    if (p == NULL)
        return NULL;
    Node *temp;
    temp=(Node*)malloc(sizeof(Node));
    //temp = new Node;
    temp->data = elem;
    temp->next = p->top;
    p->top = temp;
    p->count++;
    return p;
}
 
//出栈 pop
Link_Stack *Pop_stack(Link_Stack *p)
{
    Node *temp;
    temp = p->top;
    if (p->top == NULL)
    {
        printf("错误:栈为空");
        return p;
    }
    else
    {
   printf("\npop success");
        p->top = p->top->next;
        free(temp);
        //delete temp;
        p->count--;
        return p;
    }
}
 
//遍历栈:输出栈中所有元素
int show_stack(Link_Stack *p)
{
    Node *temp;
    temp = p->top;
    if (p->top == NULL)
    {
        printf("");
        printf("错误:栈为空");
        return 0;
    }
    while (temp != NULL)
    {
        printf("%d\t", temp->data);
        temp = temp->next;
    }
    printf("\n");
    return 0;
}
 
int main()
{ //用主函数测试一下功能
 int i;
    Link_Stack *p;
    p = Creat_stack();
    int n = 5;
    int input[6] = {10,20,30,40,50,60};
    /以依次入栈的方式创建整个栈//
    for(i=0;i<n;i++){
        Push_stack(p, input[i]);
    }
    show_stack(p);
    出栈///
    Pop_stack(p);
    show_stack(p);
    return 0;
}

The compilation result is as follows:

Summary about the stack

Stack-It is a linear table with limited operations. It can be used in number system conversion, bracket matching check, expression evaluation, etc., and it can solve problems more simply.

That's it for today's stack basics. See you in the next issue!

Recommended reading:

嵌入式编程专辑Linux 学习专辑C/C++编程专辑

关注微信公众号『技术让梦想更伟大』,后台回复“m”查看更多内容,回复“加群”加入技术交流群。
长按前往图中包含的公众号关注

Guess you like

Origin blog.csdn.net/u012846795/article/details/108480781