栈简介
栈是一种先进后出(FILO,First-In-Last-Out)的线性表,栈和队列非常相像,但是栈只能在栈顶插入和删除元素。
栈 的最后一个元素我们叫它为栈顶元素,新加入的元素我们叫元素入栈,删除末尾元素出栈,当然出栈前提是栈里要有元素。栈有一个重要的性质,就是 先进后出,First In Last Out(FILO)。
我们在构造栈的时候,仅需要用一个变量记住当前栈顶的位置,在数组构造的栈中这个变量被称为栈顶指针。
数组实现栈的基本操作
/*************************************************************************
> File Name: 4.stack.c
> Author: 陈杰
> Mail: 15193162746@163.com
> Created Time: 2021年03月31日 星期三 20时21分57秒
> 栈的实现及基本操作
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct Stack {
int *data;
int top, size;
} Stack;
/*
* 栈的初始化
* @param n: 栈的存储空间大小
* */
Stack *init(int n) {
Stack *s = (Stack *)malloc(sizeof(Stack));
s->data = (int *)malloc(sizeof(int) * n);
s->size = n;
s->top = -1;
return s;
}
/*
* 栈的扩容
* @param s: 要操作栈的指针
* */
int expand(Stack *s) {
if(s == NULL) return 0; // 判断栈是否已经被初始化
int extr_size = s->size;
int *p = NULL;
while(extr_size) {
p = (int *)realloc(s->data,sizeof(int) * (s->size + extr_size));
if(p) {
s->data = p;
s->size = s->size + extr_size;
return 1;
}
extr_size >>= 1; // 扩容容量大小减半
}
return 0;
}
/*
* 判空
* @param s: 要操作栈的指针
* */
int empty(Stack *s) {
return s->top == -1;
}
/*
* 入栈
* @param s: 要操作栈的指针
* @param val: 入栈元素的值
* */
int push(Stack *s, int val){
if(s == NULL) return 0; // 判断栈是否已经被初始化
if(s->top == s->size - 1 && !expand(s)) return 0; // 判断栈是否已满
s->data[++(s->top)] = val;
return 1;
}
/*
* 出栈
* @param s: 要操作栈的指针
* */
int pop(Stack *s) {
if(s == NULL || empty(s)) return 0; // 判断栈是否存在或已空
s->top--;
return 1;
}
/*
* 获得栈顶元素
* @param s: 要操作栈的指针
* */
int top(Stack *s) {
return s->data[s->top];
}
/*
* 栈的释放
* @param: 要操作栈的指针
* */
void clear(Stack *s) {
if(s == NULL) return; // 判断栈是否已经被初始化
free(s->data);
free(s);
}
/*
* 打印栈
* @param: 要操作栈的指针
* */
void output(Stack *s) {
if(s == NULL) return;
printf("Stack :[");
for(int i = 0; i <= s->top; i++) {
i == 0 || printf(" ");
printf("%d", s->data[i]);
}
printf("]\n");
}
int main() {
srand(time(0));
#define MAX_OP 20
Stack *s = init(MAX_OP);
for(int i = 0; i < MAX_OP; i++) {
int op = rand() % 4;
int val = rand() % 100;
if(op) printf("push %d to Stack = %d\n", val, push(s, val));
else if(!empty(s)) printf("%d pop out from Queue", top(s)), printf("= %d\n",pop(s));
else printf("fail top pop a item!\n");
output(s),printf("\n");
}
clear(s);
#undef MAX_OP
return 0;
}
链表实现栈的基本操作
/*************************************************************************
> File Name: 4.stack_link.c
> Author: 陈杰
> Mail: 15193162746@163.com
> Created Time: 2021年03月31日 星期三 21时00分24秒
> 链表实现栈的基本操作
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct Node{
int data;
struct Node *next;
} Node;
typedef struct Stack{
int size;
Node *head;
} Stack;
/*
* 获取一个赋值节点
* @param val: 新节点的值
* */
Node *getNode(int val) {
Node *node = (Node *)malloc(sizeof(Node));
node->data = val;
node->next = NULL;
return node;
}
/*
* 栈的初始化
* */
Stack *init() {
Stack *s = (Stack *)malloc(sizeof(Stack));
s->size = 0;
s->head = NULL;
return s;
}
/*
* 判空
* @param s: 要操作栈的指针
* */
int empty(Stack *s) {
return s->head == NULL;
}
/*
* 入栈
* @param s: 要操作栈的指针
* @param val: 要入栈元素的值
* */
int push(Stack *s, int val) {
if(s == NULL) return 0; // 判断栈是否已经初始化
Node *node = getNode(val);
node->next = s->head;
s->head = node;
s->size++;
return 1;
}
/*
* 出栈
* @param s: 要操作栈的指针
* */
int pop(Stack *s) {
if(s == NULL) return 0; // 判断栈是否已经初始化
if(empty(s)) return 0; // 判断栈是否为空
s->head = s->head->next;
s->size--;
return 1;
}
/*
* 获取栈顶元素的值
* @param s: 要操作栈的指针
* */
int top(Stack *s) {
return s->head->data;
}
/*
* 清理栈
* @param s: 要操作栈的指针
* */
void clear(Stack *s) {
if(s == NULL) return; // 判断栈是否已经初始化
while(s->head) {
Node *delete_node = s->head;
s->head = s->head->next;
free(delete_node);
}
free(s);
}
/*
* 打印栈
* @param s: 要操作栈的指针
* */
void output(Stack *s) {
if(s == NULL) return; // 判断栈是否已经初始化
printf("Stack :[");
Node *p = s->head;
while(p) {
printf("%d ", p->data);
p = p->next;
}
printf("]\n");
}
int main() {
srand(time(0));
#define MAX_OP 20
Stack *s = init(MAX_OP);
for(int i = 0; i < MAX_OP; i++) {
int op = rand() % 4;
int val = rand() % 100;
if(op) printf("push %d to Stack = %d\n", val, push(s, val));
else if(!empty(s)) printf("%d pop out from Stack", top(s)),printf(" = %d\n",pop(s));
else printf("fail to pop a item!\n");
output(s),printf("\n");
}
clear(s);
#undef MAX_OP
return 0;
}
数组模拟栈
/*************************************************************************
> File Name: 4.stack_temp.c
> Author: 陈杰
> Mail: 15193162756@163.com
> Created Time: 2021年03月31日 星期三 21时24分03秒
> 刷题过程中的临时栈
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_N 10
int stack[MAX_N];
int top = -1;
/*
* 打印栈
* (为了查看方便,实际操作中并不需要)
* */
void output() {
printf("Stack :[");
for(int i = 0; i <= top; i++) {
i == 0 || printf(" ");
printf("%d", stack[i]);
}
printf("]\n");
}
int main() {
srand(time(0));
#define MAX_OP 20
for(int i = 0; i < MAX_OP; i++) {
int val = rand() % 100;
int op = rand() % 4;
if(op) {
// 入栈操作
if(top < MAX_N) {
stack[++top] = val;
printf("push %d to Stack = 1\n", val);
}else printf("push fail, stack already fall!\n");
}else {
// 出栈操作
if(top >= 0) {
printf("%d pop out from Stack = 1\n", stack[top]);
top--;
}else printf("fail to pop a item!\n");
}
output(),printf("\n");
}
#undef MAX_OP
return 0;
}