个人技术分享

简介

   在之前的几篇文章中已经详细讲解了线性表中的 顺序表、单链表。每一种不同的数据结构都有它独特的结构和应用之处,今天将再次给大家介绍一个新的线性表:

1. 栈:一种特殊的线性表,其中只允许在固定的一端进行插入和删除元素的操作。

2. 栈的原型:其中进行数据插入的和删除操作的一端称为栈顶,另一端称为栈底。

3. 栈的原则:栈中的数据元素遵守 后进先出(LIFO)的原则   

4. 栈的场景:在日常生活中,(电梯)就相当于一个栈,先进去的人后出,后进去的人总是先出   

🔑栈的两个经典操作:
压栈:栈的插入操作叫做 进栈 / 压栈  / 入栈  (入数据在栈顶)

出栈:栈的删除操作叫做出栈。(出数据也在栈顶)

顺序存储栈

顺序存储栈是栈的顺序实现。顺序栈是指利用顺序存储结构(数组)实现的栈。采用地址连续的存储空间依次存储栈中数据元素。

main.c

#include <stdlib.h>
#include <stdio.h>
#include "sqstack.h"

int main()
{
    sqstack*st;
    st = st_create();
    if(st == NULL)
        exit(1);
    datatype arr[] = {11,22,33,44,55,66,77,88};
    for(int i=0;i<8;i++)
    {
        st_push(st,&arr[i]);
    }
    datatype temp;
    st_travel(st);
    while(st_pop(st,&temp)==0)
    {
        printf("POP %d \n",temp);
    }
    
    st_destroy(st);
    return 0;
}

sqstack.h

#ifndef SQSTACK_H
#define SQSTACK_H
#define MAXSIZE 5
typedef int datatype;

typedef struct node_st
{
    datatype data[MAXSIZE];
    int top;
}sqstack;


sqstack* st_create(void);

int st_isempty(sqstack*);

int st_push(sqstack*,datatype*);

int st_pop(sqstack*,datatype*);

int st_top(sqstack*,datatype*);

void st_travel(sqstack*);

int st_destroy(sqstack*);

#endif

sqstack.c

#include <stdlib.h>
#include <stdio.h>
#include "sqstack.h"

sqstack* st_create(void)
{
    sqstack*st;
    st = malloc(sizeof(*st));
    if(st == NULL)
        return NULL;
        
    st->top = -1;
    return st;
}
int st_isempty(sqstack*st)
{
    if(st->top == -1)
        return 0;
    return 1;
}
int st_push(sqstack*st,datatype* data)
{
    if(st->top == MAXSIZE-1 )
        return -1;
    st->data[++st->top] = *data;
    return 0;
}
int st_pop(sqstack*st,datatype*data)
{
    if(st_isempty(st) == 0)
        return -1;
    *data = st->data[st->top--];
    return 0;
}
int st_top(sqstack*st,datatype*data)
{
    if(st_isempty(st )== 0)
        return -1;
    *data = st->data[st->top];

}
void st_travel(sqstack*st)
{
    if(st_isempty(st)== 0)
        return;
    for(int i=0;i<=st->top;i++)
    {
        printf("%d ",st->data[i]);
    }
    printf("\n");
}

int st_destroy(sqstack*st)
{
    free(st);
    st = NULL;
    return 0;
}

链式存储栈

本文的链式存储为对上一篇文章(链表高级篇)中的双向链表(lib2)的内容进行封装生成的二次使用,如大家感兴趣可以去上篇文章找下源码,也可以给我留言,我给大家私发代码。

main.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"

struct score_st
{
    int id;
    char name[32];
    int math;
    int chinese;
};

void print_s(const void *record)
{
    const struct score_st*r = record;
    printf("%d %s %d %d \n",r->id,r->name,r->math ,r->chinese);

}

int main()
{
    int ret; 
    STACK* st = stack_create(sizeof(struct score_st));
    struct score_st temp;
    if(st == NULL)
        return -1;
    for(int i=0;i<5;i++)
    {
        temp.id = i;
        snprintf(temp.name,sizeof(temp.name),"std_%d",i);
        temp.math = rand()%100;
        temp.chinese = rand()%100;
        stack_push(st,&temp);
    }
    while(1)
    {
        ret = stack_pop(st,&temp);
        if(ret == -1)
            break;
        print_s(&temp);
    }

    stack_destroy(st);
    return 0;
}

stack.c

#include <stdlib.h>
#include <stdio.h>
#include "stack.h"


STACK* stack_create(int initsize)
{
    return llist_create(initsize);

}

int stack_push(STACK*ptr,const void *data)
{
    return llist_insert(ptr,data,LLIST_FORWARD);
}

static int always_match(const void*p1,const void*p2)
{
    return 0;
}
int stack_pop(STACK*ptr ,void* data)
{
    return llist_fetch(ptr,(void*)0,always_match,data);
}
void stack_destroy(STACK* ptr)
{

    return llist_destroy(ptr);
}

stack.h

#ifndef STACK_H
#define STACK_H

#include "llist.h"


typedef LLIST STACK;

STACK* stack_create(int);

int stack_push(STACK*,const void *data);

int stack_pop(STACK* ,void* daata);

void stack_destroy(STACK*);


#endif