数据结构学习——C语言对栈的基本操作

这篇具有很好参考价值的文章主要介绍了数据结构学习——C语言对栈的基本操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 一、栈的介绍

         栈(Stack)是一种常用的数据结构,遵循先进后出(LIFO)的原则,对表尾进行操作,常用于临时存储和撤销等操作,其基本操作包括栈的创建、入栈(也叫压栈Push)、出栈(又称弹栈)、栈的遍历、栈的清空(clear)、栈的销毁(destroy)等。

c语言栈的实现以及操作,数据结构学习,c语言,数据结构,学习

二、数组方式——栈的基本操作

        栈的创建有两种方式,一种是通过数组的方式,另一种是通过指针的方式,两种方式的原理都遵循栈的基本原理。

2.1 栈的创建以及初始化

        宏定义栈的最大大小,创建结构体,这里都用的int类型,初始化栈,将栈顶和栈底指针均置为 -1 表示此时为一个空栈。

typedef int MyInt;
#define STACK_SIZE 20

typedef struct{
    MyInt data[STACK_SIZE];
    MyInt top;
    MyInt bottom;
}Stack;

void StackInit(Stack *s){
    s->top = -1;
    s->bottom = -1;
}

2.2 入栈函数(压栈操作)

        需要注意的是,插入第一个元素之前,栈顶和栈底的指向均为 -1 ,在插入第一个值时,需要将栈顶和栈底均置为0,因为这里栈底和栈顶为 -1 的时候表示还没有插入任何的元素。

void PushStack(Stack* s,int data){
    if(s->top == STACK_SIZE - 1){
        //栈满
        printf("this Stack is full\n");
        return;
    }
    if(s->top == -1){
        //空栈,第一次插入元素,初始化栈底
        s->bottom = 0;
    }
    //栈顶指针向上移动,指向栈底
    s->top++;
    //当前节点插入元素
    s->data[s->top] = data;
}

2.3 出栈函数(弹栈操作)

        出栈遵循先进后出的原理,因此这里每次调用出栈函数只删除最后一个元素,还需要改变栈顶的指向,使栈顶的指向向下移动一个,指向上一个进栈的元素,并且定义int类型的变量将出栈的元素记录下来。

MyInt PopStack(Stack* s){
    if(s->top == -1){
        //空栈,没有元素可供删除
        printf("Stack is empty\n");
        return -1;
    }
    //定义变量pop_data表示要出栈的元素
    MyInt pop_data = s->data[s->top];
    //栈顶指针下移
    s->top--;

    if(s->top == -1)//栈为空时,重置栈底指针
    s->bottom = -1;
    //传回出栈元素
    return pop_data;
}

2.4 清栈函数(只清空数据)

        清栈函数只清除元素的数据,并不改变栈顶和栈底的指向,原来有多少个元素在进行清栈操作后依然有多少个元素,元素个数不会发生改变,但内容均为 0 ,销毁一个栈即栈为空,需要移动栈顶指针,只需在清栈同时移动栈顶指针即可。

void ClearStack(Stack* s){
    if(s->top == -1){
        printf("this Stack is empty\n");
        return;
    }
    for(int i = s->top; i >= s->bottom; i--){
        s->data[i] = 0;
        //若需销毁栈操作时,需要移动top指针
        //s->top--;
    }
    //只清空数据不改变栈顶和栈底
}

2.5 栈的遍历

        栈的遍历这里也遵循了先进后出的原理,遍历的时候从最前面的元素往后遍历,不改变栈顶指向,这里定义变量 i 进行循环操作,并且判断当栈顶 top 为 -1 的时候表示该栈中已经没有元素了,是一个空栈。

void PrintStack(Stack* s){
    if(s->top == -1){
        //空栈
        printf("Stack is empty\n");
        return;
    }
    printf("栈中的元素为:\n");
    for( int i = s->bottom; i <= s->top; i++){
        printf("%d  ",s->data[i]);
    }
    printf("\n");
}

2.6 主函数测试

        

int main(){
    Stack stack;
    StackInit(&stack);
    
    PushStack(&stack,1);
    PushStack(&stack,2);
    PushStack(&stack,3);
    PrintStack(&stack);
   
    int delete = PopStack(&stack);
    PrintStack(&stack);
    printf("被删除的元素:%d\n",delete);

    ClearStack(&stack);
    PrintStack(&stack);

    return 0 ;
}

2.7 结果输出以及代码

        输出结果:

c语言栈的实现以及操作,数据结构学习,c语言,数据结构,学习

        全部代码:

 

#include<stdio.h>

typedef int MyInt;
#define STACK_SIZE 20

typedef struct{
    MyInt data[STACK_SIZE];
    MyInt top;
    MyInt bottom;
}Stack;

void StackInit(Stack *s){
    s->top = -1;
    s->bottom = -1;
}

void PushStack(Stack* s,int data){
    if(s->top == STACK_SIZE - 1){
        //栈满
        printf("this Stack is full\n");
        return;
    }
    if(s->top == -1){
        //空栈,第一次插入元素,初始化栈底
        s->bottom = 0;
    }
    //栈顶指针向上移动,指向栈底
    s->top++;
    //当前节点插入元素
    s->data[s->top] = data;
}

MyInt PopStack(Stack* s){
    if(s->top == -1){
        //空栈,没有元素可供删除
        printf("Stack is empty\n");
        return -1;
    }
    //定义变量pop_data表示要出栈的元素
    MyInt pop_data = s->data[s->top];
    //栈顶指针下移
    s->top--;

    if(s->top == -1)//栈为空时,重置栈底指针
    s->bottom = -1;
    //传回出栈元素
    return pop_data;
}

void PrintStack(Stack* s){
    if(s->top == -1){
        //空栈
        printf("Stack is empty\n");
        return;
    }
    printf("栈中的元素为:\n");
    for( int i = s->bottom; i <= s->top; i++){
        printf("%d  ",s->data[i]);
    }
    printf("\n");
}

void ClearStack(Stack* s){
    if(s->top == -1){
        printf("this Stack is empty\n");
        return;
    }
    for(int i = s->top; i >= s->bottom; i--){
        s->data[i] = 0;
    }
    //只清空数据不改变栈顶和栈底
}

int main(){
    Stack stack;
    StackInit(&stack);
    
    PushStack(&stack,1);
    PushStack(&stack,2);
    PushStack(&stack,3);
    PrintStack(&stack);
   
    int delete = PopStack(&stack);
    PrintStack(&stack);
    printf("被删除的元素:%d\n",delete);

    ClearStack(&stack);
    PrintStack(&stack);

    return 0 ;
}

三、指针方式——栈的基本操作

3.1 栈的创建以及初始化

        首先定义结构体,其成员包括栈顶指针和栈底指针,最大长度。宏定义栈的初始大小和增量大小,当该栈满了的时候,重新为其分配内存大小,一次分配 STACK_SIZE_ADD 个长度,初始化栈的栈顶和栈底相同,并且初始大小为 STACK_INIT_SIZE。

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>


#define STACK_INIT_SIZE 10
#define STACK_SIZE_ADD 10

typedef char ElemType;

typedef struct{
    ElemType *top;  //栈顶指针
    ElemType *base; //栈底指针
    int MaxSize;    //最大长度
}stack;

void init_stack(stack *s){
    //分配初始内存大小
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    //判断内存是否分配成功
    if( !s->base ){
        printf("内存分配失败\n");
        return;
    }
    //初始化栈顶和栈底指向相同
    s->top = s->base;
    //初始化栈的最大大小
    s->MaxSize = STACK_INIT_SIZE;
}

3.2 入栈函数

        调用入栈函数先判断该栈是否超过了最大长度,若超过则重新分配内存大小,并且给栈底赋值后栈顶指针指向下一个元素,此代码中栈顶指针top除初始化外始终指向最后一个元素的下一个空元素。

void push_stack(stack *s,ElemType value){
    //判断栈是否超过了最大长度
    if(s->top - s->base >= s->MaxSize){
        //relloc 重新分配内存,有两个参数,分别是指向地址的指针和内存大小
        s->base = (ElemType *)realloc(s->base,(s->MaxSize + STACK_SIZE_ADD) * sizeof(ElemType));
        if(!s->base){
            printf("内存分配失败\n");
            return;
        }
    }
    *(s->top) = value;
    //top指针向上移动,指向下一个元素,此时还没有内容
    s->top++;
}

3.3 出栈函数

        出栈函数相对入栈简单很多,需要注意的是当该栈为空的时候已经不能进行出栈操作,因此要先判断该栈是否为空,直接将栈顶指针指向先前进栈的元素即可。

ElemType pop_stack(stack *s){
    //判断是否为空栈
    if(s->top == s->base){
        printf("该栈为空!\n");
        return -1;
    }
    return *--(s->top); 
}

3.4 清栈函数

        这里的清栈将栈中全部的元素均进行置零,不改变栈顶指针的指向,因此需要重新定义指针用于遍历清零。

void clear_stack(stack *s){
    ElemType *p = s->base;
    if(s->top == s->base){
        printf("该栈为空!\n");
        return;
    }
    for( ; p != s->top; p++){
        *p = 0;
    }
}

3.5 栈的遍历

void Print_stack(stack s){
    //判断是否为空栈
    if(s.top == s.base){
        printf("该栈为空!\n");
        return;
    }
    ElemType *p = s.base;
    printf("栈中的元素为:\n");
    while(p < s.top){
        printf("%d  ",*p);
        p++;
    }
    printf("\n");
}

3.6 销毁一个栈

        销毁一个栈只需要将结构体指针置为空,并且将分配的内存释放即可,注意需避免对空栈进行销毁。

void destroy_stack(stack *s){
    if(s->base != NULL){
        free(s->base);
        s->top = NULL;
        s->base = NULL;
        s->MaxSize = 0;
        printf("该栈销毁成功\n");
        return;
    }
    printf("该栈为空,无法进一步销毁\n");
}

3.7 主函数

int main(){

    stack myStack;
    init_stack(&myStack);

    push_stack(&myStack,1);
    push_stack(&myStack,2);
    push_stack(&myStack,3);
    Print_stack(myStack);
   
    printf("删除的元素是:  %d\n",pop_stack(&myStack));
    Print_stack(myStack);
    
    clear_stack(&myStack);
    Print_stack(myStack);

    destroy_stack(&myStack);
    destroy_stack(&myStack);
    return 0;
}

3.8 全部代码:

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>


#define STACK_INIT_SIZE 10
#define STACK_SIZE_ADD 10

typedef char ElemType;

typedef struct{
    ElemType *top;  //栈顶指针
    ElemType *base; //栈底指针
    int MaxSize;    //最大长度
}stack;

void init_stack(stack *s){
    //分配初始内存大小
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    //判断内存是否分配成功
    if( !s->base ){
        printf("内存分配失败\n");
        return;
    }
    //初始化栈顶和栈底指向相同
    s->top = s->base;
    //初始化栈的最大大小
    s->MaxSize = STACK_INIT_SIZE;
}

void push_stack(stack *s,ElemType value){
    //判断栈是否超过了最大长度
    if(s->top - s->base >= s->MaxSize){
        //relloc 重新分配内存,有两个参数,分别是指向地址的指针和内存大小
        s->base = (ElemType *)realloc(s->base,(s->MaxSize + STACK_SIZE_ADD) * sizeof(ElemType));
        if(!s->base){
            printf("内存分配失败\n");
            return;
        }
    }
    *(s->top) = value;
    //top指针向上移动,指向下一个元素,此时还没有内容
    s->top++;
}

ElemType pop_stack(stack *s){
    //判断是否为空栈
    if(s->top == s->base){
        printf("该栈为空!\n");
        return -1;
    }
    return *--(s->top); 
}

void Print_stack(stack s){
    //判断是否为空栈
    if(s.top == s.base){
        printf("该栈为空!\n");
        return;
    }
    ElemType *p = s.base;
    printf("栈中的元素为:\n");
    while(p < s.top){
        printf("%d  ",*p);
        p++;
    }
    printf("\n");
}

void clear_stack(stack *s){
    ElemType *p = s->base;
    if(s->top == s->base){
        printf("该栈为空!\n");
        return;
    }
    for( ; p != s->top; p++){
        *p = 0;
    }
}

void destroy_stack(stack *s){
    if(s->base != NULL){
        free(s->base);
        s->top = NULL;
        s->base = NULL;
        s->MaxSize = 0;
        printf("该栈销毁成功\n");
        return;
    }
    printf("该栈为空,无法进一步销毁\n");
}

int main(){

    stack myStack;
    init_stack(&myStack);

    push_stack(&myStack,1);
    push_stack(&myStack,2);
    push_stack(&myStack,3);
    Print_stack(myStack);
   
    printf("删除的元素是:  %d\n",pop_stack(&myStack));
    Print_stack(myStack);
    
    clear_stack(&myStack);
    Print_stack(myStack);

    destroy_stack(&myStack);
    destroy_stack(&myStack);
    return 0;
}

输出结果:

c语言栈的实现以及操作,数据结构学习,c语言,数据结构,学习

 四、总结

        对栈的各种操作时需要注意内存使用的问题,注意判断栈顶指针的指向,栈底指针的指向,栈的内存分配,遵循先进后出的原则,在使用后需要对栈进行内存释放。文章来源地址https://www.toymoban.com/news/detail-722454.html

到了这里,关于数据结构学习——C语言对栈的基本操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】栈和队列(栈的基本操作和基础知识)

    🌈个人主页: 秦jh__ https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343 🔥 系列专栏: 《数据结构》 https://blog.csdn.net/qinjh_/category_12536791.html?spm=1001.2014.3001.5482 目录  前言 栈 栈的概念和结构 栈的实现 ​编辑 数组栈的实现 总的声明 初始化  插入 删除 取栈顶元素 销毁 判断是否为空

    2024年02月03日
    浏览(54)
  • 数据结构:使用顺序栈的基本操作,实现十进制转为二进制,十六进制的转换

    使用系统环境: 1:win10,使用工具dev 2:使用系统win10 3:参考书籍数据结构(C语言版——严蔚敏 吴伟民) ( 注意:此文章默认,学习者拥有一定的数据机构栈,C语言的知识,书籍第20页,2.1算法的代码进行一个简化。)

    2024年02月05日
    浏览(66)
  • 【数据结构】顺序栈和链栈的基本操作(定义,初始化, 入栈,出栈,取栈顶元素,遍历,置空)

    🎊专栏【数据结构】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【勋章】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰   目录 ⭐栈的分类 ✨顺序栈 🎈优点: 🎈缺点: ✨链栈 🎈优点: 🎈缺点: ⭐基本概念 ✨栈: ✨栈顶: ✨栈顶: ✨图片理

    2023年04月22日
    浏览(56)
  • 【数据结构】顺序栈的基本操作:出栈、入栈、取栈顶元素、输出所有栈中元素、括号匹配题目

    栈是限定仅在表位进行插入或删除操作的线性表。栈的表尾称为栈顶,表头称为栈底。不含元素的栈称为空栈。 左图为栈的示意图,右图为用铁路调度表示栈。 如下是入栈至栈满再进行出栈的过程示意图。值得注意的是,栈满后,top指针指向的不是顶端元素,而是顶端的下

    2024年02月07日
    浏览(55)
  • 【数据结构】栈的实现(C语言)

    文章目录 1.栈 1.1 栈的定义 1.2 C语言实现栈 1.2.1接口函数 1.2.2栈的创建 1.2.3栈的初始化  1.2.4栈的销毁 1.2.5压栈 1.2.6出栈 1.2.7判断栈是否为空 1.2.8取栈顶元素 1.2.9 栈有多少个数据  1.3 C语言实现栈的具体代码 头文件stack.h 接口函数stack.c 测试函数test.c         栈(stack)又名堆

    2024年02月05日
    浏览(46)
  • 数据结构-栈的实现(C语言版)

    前言         栈是一种特殊的线性表,只允许在固定的一端进行插入和删除的操作, 进行数据插入和删除的一端叫做栈顶,另一端叫做栈底。  栈中的数据元素遵循后进先出的的原则。 目录 1.压栈和出栈 2. 栈的实现 3.测试代码         压栈:栈的插入操作叫 压栈,入数

    2024年02月13日
    浏览(50)
  • 【数据结构 迷宫问题求解】栈的应用|c语言|迷宫问题

    亲测可行: 使用蓝桥杯比赛编译器:DEV C++  求迷宫中从入口到出口的路径是一个经典的程序设计问题,通常采用“穷举求解”的方法,即顺着某一方向向前探索,若能走通,则继续往前走;否则原路返回,换一个方向继续探索,直至所有可能的通路都探索到为止。 因此,在

    2024年02月08日
    浏览(49)
  • 『初阶数据结构 • C语言』⑩ - 栈的概念与实现(附完整源码)

        栈存储数据的方式跟数组一样,都是将元素排成一行。只不过它还有以下 3 条约束。   ● 只能在末尾插入数据。   ● 只能读取末尾的数据。   ● 只能移除末尾的数据。 你可以将栈看成一叠碟子:你只能看到最顶端那只碟子的碟面,其他都看不到。另外,要加碟子只能

    2024年02月16日
    浏览(50)
  • 【数据结构】队列基本操作的实现(C语言)

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:🛹数据结构、🛴C++ 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与

    2024年02月16日
    浏览(51)
  • 【数据结构】顺序表基本操作的实现(C语言)

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:🛹数据结构、🛴C++ 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与

    2024年02月16日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包