C语言栈的实现

发布于:2025-08-13 ⋅ 阅读:(18) ⋅ 点赞:(0)

C语言栈

//表示栈
typedef struct stack{
    int* arr;//存储区的首地址
    int top; //控制存和取的操作
    int cap; //存储区的容量
}stack_t;

思路:

入栈操作:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

中间都是重复的步骤,就省略了。

在这里插入图片描述
在这里插入图片描述

出栈操作:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

中间都是重复的步骤,就省略了。

在这里插入图片描述
在这里插入图片描述

栈空的情况:

在这里插入图片描述
注意哈,这个top表示的是数组下标。第一个数组的下标为0

栈满的情况:

在这里插入图片描述

存储区容量 cap = 11 ,意味着栈最多能存 11 个元素(对应数组下标 0 ~ 10 ,共11个可用位置 )。
top 表示下一个要存入数据的数组下标 ,初始为 0 。每存一个数据,top+1 指向下一个位置 。
top == cap(即 top = 11 )时,说明下一个要存的位置已经超出了数组最大下标(10 ),此时栈里已经存了cap个元素(下标0~10全占满 ),栈满,无法再存新数据。

具体代码实现:

1. 栈的头文件
//stack.h文件
//栈的头文件,谁包含我的这个头文件,谁就可以用我这个类型的声明和函数的声明
//头文件卫士,避免头文件被重复包含
#ifndef __STACK_H__
#define __STACK_H__

//一.类型的声明
//用结构体表示栈
typedef struct stack{
    int* arr;//存储区的首地址
    int top;//控制存和取的操作
    int cap;//存储区的容量
}stack_t;
//定义栈类型的变量  stack_t s;
//定义变量的同时得初始化,我们可以将这个初始化操作封装到函数void stack_init(stack_t* p,int cap);里面

//二.函数的声明
//栈的初始化
//参数:指向要初始化的栈的指针;栈的容量
//对指针p所指向的栈进行初始化,容量为cap
void stack_init(stack_t* p,int cap);

//栈的释放
//参数:指向要释放的栈的指针
//对指针p所指向的栈进行释放
void stack_deinit(stack_t* p);

//栈的判空
//参数:指向要判断的栈的指针
//如果指针p所指向的栈是空的,返回1;非空则返回0
int stack_empty(stack_t* p);

//栈的判满
//参数:指向要判断的栈的指针
//如果指针p所指向的栈是满的,返回1;非满则返回0
int stack_full(stack_t* p);

//压栈
//第一个参数:指向要存入数据的栈的指针
//第二个参数:要入栈的数据,传入该数据后会被存到指针p所指向的栈里面
void stack_push(stack_t* p,int data);

//弹栈
//参数:指向要取出数据的栈的指针
//从指针p所指向的栈里面取出数据,返回取出的int类型数据
int stack_pop(stack_t* p);

#endif
2.栈的实现
//stack.c文件
//栈的实现
#include<stdlib.h>//malloc() free()
#include"stack.h"

//栈的初始化
//参数:指向要初始化的栈的指针;栈的容量
//stack_t s; s.arr s.top s.cap
//stack_init(&s,5);//实参
void stack_init(stack_t* p,int cap){//形参
    // p &s; cap = 5;
    // malloc返回值是void*类型,可以强转变成int*,也可以不写,因为编译器会自动进行隐式类型转换
    // 隐式类型转换:整转浮,有转无,小转大
    p->arr = (int*)malloc(sizeof(int) * cap);
    p->top = 0;
    p->cap = cap;
}

//栈的释放
//参数:指向要释放的栈的指针
//stack_t s; s.arr s.top; s.cap
//stack_deinit(&s);//实参
void stack_deinit(stack_t* p){//形参
    free(p->arr);
    p->arr = NULL;
    p->top = 0;
    p->cap = 0;
}

//栈的判空
//参数:指向要判断的栈的指针
//当指针p所指向的栈中没有存储数据(top为0)时,返回1;否则返回0
int stack_empty(stack_t* p){
    if(p->top == 0){
        return 1;
    }else{
        return 0;
    }
}

//栈的判满
//参数:指向要判断的栈的指针
//当指针p所指向的栈中存储数据已满(top等于cap)时,返回1;否则返回0
int stack_full(stack_t* p){
    //return p->top == p->cap ? 1 : 0;
    return p->top == p->cap;
}

//压栈
//参数:指向目标栈的指针;要入栈的数据
//把data的数据存到栈里面,存到arr里面,top作下标,arr[top] = data,存完之后top的值+1
void stack_push(stack_t* p,int data){
    //谁的arr谁的top,结构体里面的呀
    //arr[top] = data;这是错误的

    //p->arr[p->top] = data;
    //p->top++;
    //上面两行可以合成下面一行(先以top的值作为下标完成数据的存储,然后top的值再加一)
    p->arr[p->top++] = data;
}

//弹栈
//参数:指向目标栈的指针
//如何拿数据:top先减一,然后以top作为下标将对应的这块存储区的数据拿出来存在val里面
int stack_pop(stack_t* p){
    //谁的top谁的arr,结构体里面的呀
    //top--;这是错误的
    //int val = arr[top];这是错误的

    p->top--;
    int val = p->arr[p->top];
    return val;
    //上面三行可以合并下面一行(先top的值减1,然后将top的值作为下标完成数据的取)
    //return p->arr[--p->top];
}
3. 栈的使用示例
//main.c
//栈的使用示例
#include<stdio.h>
#include"stack.h"
int main(void){

    //定义栈
    stack_t s;
    //栈的初始化:容量为11
    stack_init(&s,11);
    int data = 1;
    
    //往栈中依次存入数据:1 2 3 4 5 6 7 8 9 10 11
    //循环结束条件:栈满时停止存入(使用栈满判断函数)
    //stack_full(&s)返回1表示栈满,返回0表示栈未满
    while(stack_full(&s) != 1){
        stack_push(&s,data);
        data++;
    }
    
    //从栈中依次取出数据并打印
    //循环结束条件:栈空时停止取出(使用栈空判断函数)
    //stack_empty(&s)返回1表示栈空,返回0表示栈非空
    while(stack_empty(&s) != 1){
        printf("%d ",stack_pop(&s));
    }
    printf("\n");

    //释放栈资源
    stack_deinit(&s);

    return 0;
}
4. linux关于这个的使用步骤

1.创建一个文件夹

mkdir stack

2.创建三个文件
其中stack.c表示的是(栈的实现)
其中stack.h表示的是栈的头文件(栈的定义)
其中main.c表示的是(栈的使用)

touch stack.c
touch stack.h
touch main.c
  1. stack.cstack.h写完之后验证一下有没有语法错误,看我的stack.o的文件能不能成功生成
gcc -c stack.c
  1. 生成最终的可执行文件
gcc main.c stack.c -o stack
  1. 运行程序
./stack
  1. 运行之后的结果:
    11 10 9 8 7 6 5 4 3 2 1

网站公告

今日签到

点亮在社区的每一天
去签到