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


Author | Li Xiaoyao

Source | Technology makes dreams greater (ID: TechDreamer)

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 can only perform two operations: 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:

  • The array stack uses arrays to simulate functions, which is faster and more convenient;

  • The linked list stack is designed with the idea of ​​linked list, which 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 the given stack of the static linked list stack is not allowed to exceed the storage of elements exceeding the given data size;

  • The dynamic stack 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 2 constants, STACK_INIT_SIZE (storage space initial allocation amount) and STACK_INCREMENT (storage space allocation increment), 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 is, top = 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. One structure Node represents the node, which contains a data field and next pointer, 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:

In the push operation, we only need to find the space pointed to by top, create a new node, point the next pointer of the new node to the space pointed to by the top pointer, and then transfer the top pointer 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 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;
    }
}


栈的基本操作—遍历

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!

更多精彩推荐
☞CSDN 今日发布开源代码托管平台 CODE.CHINA
☞乘“峰”而上,聚生态之力共创软件产业新未来

☞腾讯微博即将关停,十年了,你用过吗?
☞Cognitive Inference:认知推理下的常识知识库资源、常识推理测试评估与中文实践项目索引
☞超详细 | 21张图带你领略集合的线程不安全
☞腾讯云区块链邀您参加2020腾讯全球数字生态大会
点分享点点赞点在看

Guess you like

Origin blog.csdn.net/csdnnews/article/details/108544140