4.栈

栈简介

栈是一种先进后出(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值