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