Stack (linear table with limited operation) --- C language version

First, the concept of stack

Definition of stack

A stack is a linear list restricted to insert or delete operations only at the end of the list. Therefore, for the stack, the tail of the table has a special meaning, which is called the top of the stack, and correspondingly, the header segment is called the bottom of the stack. An empty list with no elements is called an empty stack.

Top of stack: The end of the linear list that allows insertions and deletions.
Bottom of the stack: A fixed end that does not allow insertion and deletion.
Empty stack: An empty list with no elements.
Operational characteristics of stack: Last In First Out (Last In First Out)

Suppose a certain stack S=(a 1 , a 2 ,..., a n ), then a 1 is called the bottom element of the stack, and a n is the top element of the stack.
The elements in the stack are pushed into the stack in the order of a 1 , a 2 ,..., an n , and the first element to be popped off the stack should be the top element of the stack.
In other words, the modification of the stack is carried out according to the principle of last-in-first-out, which can be referred to as LIFO;

Schematic diagram of the stack:
insert image description here

Mathematical properties of stacks

n different elements are pushed into the stack, and the number of different permutations of the popped elements is 1 n + 1 C 2 nn \frac{1}{n+1}C_{2n}^nn+11C2 nn. This formula is called the Cattelan number.

Second, the basic operation of the stack

  • InitStack(*S): constructs an empty stack S
  • StackEmpty(S): Returns TRUE if stack S is empty, otherwise FALSE.
  • Push(*S,e): Insert element e as the new top element of the stack
  • Pop(*S,*e): Remove the top element of S from the stack and return its value with e.
  • StackLength(S): Returns the number of elements in the stack S, that is, the length of the stack.
  • GetTop(S,*e): use e to return the top element of the stack
  • StackTraverse(S): Traverse the stack S from the bottom of the stack to the top of the stack, and print the elements in it
  • DestoryStack(*S): destroy stack
  • ClearStack(*S): stack S is cleared to empty stack

Next, it is divided into sequential storage and chain storage of the stack to implement these operations.

3. Sequential stack

A stack that uses sequential storage is called a sequential stack, which uses a group of storage units with consecutive addresses to store data elements from the bottom of the stack to the top of the stack.

3.1 Definition of sequential stack

The sequence stack is actually a sequence table with limited operations, and we use dynamic allocation here. For the content of the sequence table, you can view the sequence table (sequential storage of linear tables) - C language version
Still using this example, how do we store the table?

id name description
1 Shi Qiang The strongest support
2 Chapter North Sea I don't need a stencil, I'm the master of my own mind
3 Luo Ji Humans don't thank Luo Ji
4 Vader Lose humanity, lose a lot. lose the beast, lose everything

Step 1: Declare the data element type

First we use the structure to declare the type of the data element (corresponding to a row of data in the table)

typedef struct{
    
    
    int id;//对应表中的id
    char name[100];//对应表中的姓名
    char description[200];//对应表中的描述
}SElemType;//此处的SElemType是个类型名

Step 2: Definition of Sequence Stack

#define InitSize 10;//栈的初始长度
#define ListIncrement 2;//扩容时的分配增量
typedef struct{
    
    
    SElemType *base;//栈的基地址,指示动态分配的数组的指针
    SElemType *top;//栈顶指针
    int MaxSize;//当前栈的最大存储长度
}SqStack;//顺序栈的类型定义
3.2 Operation of sequential stack
  • The stack structure does not exist:base==NULL;
  • The stack is empty:base==top
  • On the stack: *top=e; top++;assign first and then add one
  • Pop the stack: top--; *e=*top;decrement first and then return
    insert image description here
InitStack(*S): constructs an empty stack S
/*初始化*/
int InitStack(SqStack *S){
    
     
   S->base=(SElemType *)malloc(sizeof(SElemType)*InitSize); //给栈分配存储空间
   if(!S->base) return FALSE; //分配失败返回FALSE
   S->top=S->base;//空栈的top和base指向同一个位置
   S->MaxSize=InitSize;//初始最大长度
   return TRUE;//成功初始化返回TRUE
}
StackEmpty(S): Returns TRUE if stack S is empty, otherwise FALSE.
/*判断是否为空栈*/
int StackEmpty(SqStack S){
    
    
    if (S.base==S.base) return TRUE;
    return FALSE;
}
Push(*S,e): Insert element e as the new top element of the stack
/*插入*/
int Push(SqStack *S,SElemType e){
    
    
    if(S->top-S->base>=S->MaxSize){
    
    
        S->base=(SElemType*)realloc(S->base,(S->MaxSize+StackIncrement)*sizeof(SElemType));//栈满追加存储空间
        if (!S->base) return FALSE;//存储分配失败
        S->top=S->base;
        S->MaxSize+=StackIncrement;
    }
    *S->top++=e;//先赋值再加一
    return TRUE;
} 
Pop(*S,*e): Remove the top element of S from the stack and return its value with e.
/*删除*/
int Pop(SqStack *S,SElemType *e){
    
       
    if (S->top==S->base) return FALSE;//如果栈为空,返回
    *e=*(--S->top);//先减一再返回  
    return TRUE;
}
StackLength(S): Returns the number of elements in the stack S, that is, the length of the stack.
/*求栈长*/
int StackLength(SqStack S){
    
    
    int length=0;
    for( ;S.base<S.top;S.base++){
    
    
        length++;
    }
    return length;
}
GetTop(S,*e): use e to return the top element of the stack
/*获取栈顶元素*/
int GetTop(SqStack S,SElemType *e){
    
    
    if (S.top==S.base) return FALSE;
    *e=*(S.top-1);
    return TRUE;  
}
StackTraverse(S): Traverse the stack S from the bottom of the stack to the top of the stack, and print the elements in it
/*打印*/
void StackTraverse(SqStack S){
    
    
    for ( ;S.base<S.top;S.base++){
    
    
        printf("id=%d,name=%s,description=%s\n",S.base->id,S.base->name,S.base->description);
    }   
}
DestoryStack(*S): destroy stack
/*销毁顺序表*/
void DestroyStack(SqStack *S){
    
    
    free(S->base);
    S->MaxSize=0;
    S->base=NULL;
    S->top=NULL;
}
ClearStack(*S): stack S is cleared to empty stack
/*清空栈*/
void ClearStack(SqStack *S){
    
    
    S->top=S->base;
}
3.3 Complete source code
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define InitSize 10  //表的初始长度
#define StackIncrement 2  //扩容时的分配增量
typedef struct{
    
    
    int id;//对应表中的id
    char name[100];//对应表中的姓名
    char description[200];//对应表中的描述
}SElemType;//此处的SElemType是个类型名

typedef struct{
    
    
    SElemType *base;//栈的基地址,指示动态分配的数组的指针
    SElemType *top;//栈顶指针
    int MaxSize;//当前栈的最大存储长度
}SqStack;//顺序栈的类型定义

/*初始化*/
int InitStack(SqStack *S){
    
     
   S->base=(SElemType *)malloc(sizeof(SElemType)*InitSize); //给栈分配存储空间
   if(!S->base) return FALSE; //分配失败返回FALSE
   S->top=S->base;//空栈的top和base指向同一个位置
   S->MaxSize=InitSize;//初始最大长度
   return TRUE;//成功初始化返回TRUE
}
int StackEmpty(SqStack S){
    
    
    if (S.base==S.base) return TRUE;
    return FALSE;
}

/*插入*/
int Push(SqStack *S,SElemType e){
    
    
    if(S->top-S->base>=S->MaxSize){
    
    
        S->base=(SElemType*)realloc(S->base,(S->MaxSize+StackIncrement)*sizeof(SElemType));//栈满追加存储空间
        if (!S->base) return FALSE;//存储分配失败
        S->top=S->base;
        S->MaxSize+=StackIncrement;
    }
    *S->top++=e;//先赋值再加一
    return TRUE;
} 

/*删除*/
int Pop(SqStack *S,SElemType *e){
    
       
    if (S->top==S->base) return FALSE;//如果栈为空,返回
    *e=*(--S->top);
    return TRUE;
}

/*求栈长*/
int StackLength(SqStack S){
    
    
    int length=0;
    for(;S.base<S.top;S.base++){
    
    
        length++;
    }
    return length;
}

/*获取栈顶元素*/
int GetTop(SqStack S,SElemType *e){
    
    
    if (S.top==S.base) return FALSE;
    *e=*(S.top-1);
    return TRUE;  
}

/*打印*/
void StackTraverse(SqStack S){
    
    
    for ( ;S.base<S.top;S.base++){
    
    
        printf("id=%d,name=%s,description=%s\n",S.base->id,S.base->name,S.base->description);
    }   
}

/*销毁顺序表*/
void DestroyStack(SqStack *S){
    
    
    free(S->base);
    S->MaxSize=0;
    S->base=NULL;
    S->top=NULL;
}

/*清空栈*/
void ClearStack(SqStack *S){
    
    
    S->top=S->base;
}

int main(void){
    
    
///初始化
    
    SqStack S;
    int i=InitStack(&S);
    if (i==1){
    
    
        printf("初始化成功\n");
    }else{
    
    
        printf("初始化失败\n"); 
    }
    printf("\n");    
///插入
    SElemType a[4]={
    
    
        {
    
    1,"史强","最强辅助"},
        {
    
    2,"章北海","我不需要钢印,我是自己思想的主人"},
        {
    
    3,"罗辑","人类不感谢罗辑"},
        {
    
    4,"维德","失去人性,失去很多。失去兽性,失去一切"}
    };
    int j;
    for ( j = 0; j < 4; j++){
    
    
        i=Push(&S,a[j]);
    }
    StackTraverse(S);
    printf("\n"); 
删除
    SElemType e;
    Pop(&S,&e);    
    printf("被删除的元素:id=%d,name=%s,description=%s\n",e.id,e.name,e.description);
    printf("删除之后:\n");
    StackTraverse(S);
    printf("\n"); 
//获取栈顶元素
    i=GetTop(S,&e);
    printf("栈顶元素:id=%d,name=%s,description=%s\n",e.id,e.name,e.description);
    printf("\n");      
//销毁查找       
    DestroyStack(&S);
    StackTraverse(S);//打印为空了
}

operation result:

初始化成功

id=1,name=史强,description=最强辅助
id=2,name=章北海,description=我不需要钢印,我是自己思想的主人
id=3,name=罗辑,description=人类不感谢罗辑
id=4,name=维德,description=失去人性,失去很多。失去兽性,失去一切

被删除的元素:id=4,name=维德,description=失去人性,失去很多。失去兽性,失去一切
删除之后:
id=1,name=史强,description=最强辅助
id=2,name=章北海,description=我不需要钢印,我是自己思想的主人
id=3,name=罗辑,description=人类不感谢罗辑

栈顶元素:id=3,name=罗辑,description=人类不感谢罗辑


4. Chain stack

Guess you like

Origin blog.csdn.net/weixin_47138646/article/details/122242857