C 数据结构 之 栈

数据结构

1. 组成

  • 一组存储区用来存放数字
  • 一组函数用来操作存储区

2. 栈 (最简单的数据结构)

  • 2.1 特点
    • 每次只能加入一个数字,每次只能拿出一个数字。
    • 栈里的数字有前后顺序,先进入的数字在最前,后进入的数字在最后。
    • 每次从栈里获得的数字一定是最后放进去的数字(后进先出)
  • 2.2 实现方法
    • 可使用宏 SIZE,在编译的时候临时决定栈里需要多少个存储区
    • 有了数字个数 qty,随时就可以知道最后一个数字放在哪个下标里,同时也可以知道下一个数字往哪个下标的存储区里放
typedef struct {
	int buf[SIZE]; //存放数字的数组
	int qty;       //栈里的数字个数
} stack;
    • 除了这个结构体外,还需要为这个栈编写一组相关的关联函数
    • 栈的初始化函数用来把一个没有使用过的栈设置成可使用的状态
      • void stack_init(stack *p_stack) {…}
    • 栈的清理函数 用来把一个使用过的栈里的所有数字删除
      • void stack_deinit(stack *p_stack){…}
    • 获得栈里的数字个数的函数
      • int stack_size(const stack *p_stack){…}
    • 判断栈是否是空的函数
      • int stack_empty(const stack *p_stack){…}
    • 判断栈是否满的函数
      • int stack_full(const stack *p_stack){…}
    • 向栈里加数字的函数(用整数类型返回值表示是否把数字加进了栈里)
      • int stack_push(stack *p_stack, int val){…}
    • 从栈里获得数字的函数(同时删除数字)
      • int stack_pop(stack *p_stack, int *p_val){…}
    • 从栈里获得数字的函数(不会删除数字
      • int stack_top(const stack *p_stack, int *p_val){…}
/
//stack_1.h
//头尾加上条件编译预处理指令
#ifndef __STACK_1_H__
#define __STACK_1_H__

typedef struct {
    int buf[SIZE];
    int qty;
} stack;

void stack_init(stack *);

void stack_deinit(stack *);

int stack_size(const stack *);

int stack_empty(const stack *);

int stack_full(const stack *);

int stack_push(stack *, int);

int stack_pop(stack *, int *);

int stack_top(const stack *, int *);

#endif //__STACK_1_H__

/
//stack_1.c
#include "stack_1.h"

//栈的初始化函数(处理一个没有使用过的栈),用结构体指针形参来代表一个栈
//要修改这个栈,所以不用加const关键字
void stack_init(stack *p_stack) {
    //qty = 0 表示栈里没有数字,所有存储区的数字都是无效的
    //所以可以不用管数组内容
    p_stack->qty = 0; 
}

//栈的清理函数(处理一个使用过的栈)
void stack_deinit(stack *p_stack) {
    //栈里没有数字就相当于把数字都删了
    p_stack->qty = 0;
}

//获得栈里数字个数的函数
int stack_size(const stack *p_stack) {
    return p_stack->qty;    
}

//判断栈是否空的函数
int stack_empty(const stack *p_stack) {
    return !p_stack->qty;
}

//判断栈是否是满的
int stack_full(const stack *p_stack) {
    return p_stack->qty >= SIZE;
}

//向栈里加入数字, val 表示要加的数字
int stack_push(stack *p_stack, int val) {
    //先判断栈是否已经满了
    if(p_stack->qty >= SIZE) {
        //如果栈满了就不可能加入新数字
        return 0;
    }
    //栈的数组有两种使用方法,第一种是先加入的数字放在小下标的存储区里
    //第二种是先加入的数字放在大下标的存储区里,这里用第一种
    //以 qty 为下标到数组里找到第一个存储区,把数字赋值给这个存储区
    p_stack->buf[p_stack->qty] = val;
    p_stack->qty++;
    return 1;
}

//从栈里获得数字的函数
//返回值用来表示是否成功的获得了数字
//这里用 整数类型指针形参 把获得的数字从 被调函数 传递给 调用函数
int stack_pop(stack *p_stack, int *p_val) {
    //检查栈是否是空的
    if (p_stack->qty == 0)
    {
        //如果栈里没有数字就无法获得数字
        return 0;
    }
    //找到以 qty - 1 作下标的存储区,它里面就是最后面的数字
    //把这个数字传递给调用函数,然后数字个数减一
    *p_val = p_stack->buf[p_stack->qty - 1];
    p_stack->qty--; 
    return 1;
}

//从栈里获得数字的函数(不会删除这个数字)
int stack_top(const stack *p_stack, int *p_val) {
    if (p_stack->qty == 0)
    {
        return 0;
    }
    *p_val = p_stack->buf[p_stack->qty - 1];
    return 1;
}

/*
//验证这个没有主函数的源文件能不能编译过
gcc -DSIZE=5 stack.cc -c
*/

/
//stack_main.c
#include <stdio.h>
//如果一个源文件里使用了某个头文件里声明的函数,那这个头文件也是这个源文件的必要头文件
#include "stack_1.h"

int main() {
    stack stk = {0};
    int val = 0;

    //使用数据结构的代码框架
    //首先做初始化, 最后做清理
    stack_init(&stk);
    printf("数字个数是%d\n", stack_size(&stk));
    printf("判断栈是空的结果是%d\n", stack_empty(&stk));
    printf("判断栈是满的结果是%d\n", stack_full(&stk));

    stack_push(&stk, 10);
    stack_push(&stk, 20);
    stack_push(&stk, 30);

    printf("数字个数是%d\n", stack_size(&stk));
    printf("判断栈是空的结果是%d\n", stack_empty(&stk));
    printf("判断栈是满的结果是%d\n", stack_full(&stk));

    stack_push(&stk, 40);
    stack_push(&stk, 50);

    printf("数字个数是%d\n", stack_size(&stk));
    printf("判断栈是空的结果是%d\n", stack_empty(&stk));
    printf("判断栈是满的结果是%d\n", stack_full(&stk));

    //拿到的一定是最后放进去的数字
    stack_top(&stk, &val);
    printf("最后的数字是%d\n", val);

    //把栈里所有数字拿出来,并删除
    while (1) {
        if(!stack_pop(&stk, &val)) {
            //负责处理不能从栈里获得数字的情况
            break;
        }
        printf("%d ", val);
    }
    printf("\n");

    printf("数字个数是%d\n", stack_size(&stk));
    printf("判断栈是空的结果是%d\n", stack_empty(&stk));
    printf("判断栈是满的结果是%d\n", stack_full(&stk));

    //最后做清理
    stack_deinit(&stk);
    return 0;
}

/*
gcc -DSIZE=5 stack_main.c stack_1.c
./a.out

数字个数是0
判断栈是空的结果是1
判断栈是满的结果是0
数字个数是3
判断栈是空的结果是0
判断栈是满的结果是0
数字个数是5
判断栈是空的结果是0
判断栈是满的结果是1
最后的数字是50
50 40 30 20 10
数字个数是0
判断栈是空的结果是1
判断栈是满的结果是0
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值