线性结构的应用-栈

简介: 定义栈是一种运算受限的线性表其限制是仅允许在表的一端进行插入和删除运算允许进行操作的一端被称为栈顶,另一端则称为栈底主要操作压栈 / 入栈 / 进栈:插入元素出栈 / 退栈:删除元素性质先进后出:最先进栈的元素,...

定义

  • 栈是一种运算受限的线性表
  • 其限制是仅允许在表的一端进行插入和删除运算
  • 允许进行操作的一端被称为栈顶,另一端则称为栈底
img_b05a9cdd9a32e0bc35bb95fb51e8c02b.png

主要操作

  • 压栈 / 入栈 / 进栈:插入元素
  • 出栈 / 退栈:删除元素

性质

  • 先进后出:最先进栈的元素,只可以最后出栈

栈的分类

  • 静态栈:用数组来实现的栈
  • 动态栈:用链表来实现的栈

动态栈的实现

img_d1cbeef48bf8ebdae13f865e7fcdb75c.png
栈结构
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
/**
    定义结点数据类型
*/
typedef struct Node{
    int data;
    struct Node * pNext;
}NODE,*PNODE;

/**
    定义栈结构
*/
typedef struct stack{
    PNODE pTop;
    PNODE pBottom;
}STACK,*PSTACK;

/**
    声明函数
*/
void init_stack(PSTACK); //初始化一个栈,即构建一个栈结构
void push_stack(PSTACK,int); //把一个元素压栈
void traverse_stack(PSTACK); //遍历栈
bool isEmpty(PSTACK);   //判断栈空
bool pop_stack(PSTACK,int *); //出栈
void clear_stack(PSTACK);   //清空栈

int main()
{
    STACK s; //定义一个栈
    //测试 初始化栈
    init_stack(&s);

    //测试 压栈
    push_stack(&s,2);
    push_stack(&s,5);
    push_stack(&s,4);
    push_stack(&s,8);

    //测试 遍历栈
    traverse_stack(&s);


    //测试清空栈
    clear_stack(&s);

    //测试 出栈
    int element;  //保存删除的元素
    if(pop_stack(&s,&element)){
        printf("删除成功,你删除的元素是:%d \n",element);
    }else{
        printf("删除失败!\n");
    }
    traverse_stack(&s);
    printf("Hello world!\n");
    return 0;
}

/**
    初始化栈
*/
void init_stack(PSTACK pStack){
    //为栈生成一个不存放任何数据的头结点,并且用栈栈底指针指向它
    pStack->pBottom = (PNODE)malloc(sizeof(NODE));
    if(pStack->pBottom == NULL){
        printf("内存分配失败,程序结束!");
        exit(-1);
    }
    //内存分配成功,也把栈顶指针指向头结点
    pStack->pTop = pStack->pBottom;

    //初始化头结点,把头结点的指针域设为NULL
    pStack->pTop->pNext=NULL;
}

/**
    把一个元素压栈
*/
void push_stack(PSTACK pStack,int element){
    //为新结点动态分配一个存储空间
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    if(pNew == NULL){
        printf("内存分配失败,程序结束!");
        exit(-1);
    }

    //把新插入元素的值放入到数据域中
    pNew->data = element;

    //压栈:把新结点挂到头结点后面
    pNew->pNext = pStack->pTop;

    //把栈顶指针指向栈顶元素
    pStack->pTop = pNew;

    return;
}

/**
    遍历栈
*/
void traverse_stack(PSTACK pStack){
    //得到栈顶元素的位置
    PNODE p = pStack->pTop;

    //遍历栈
    while(p != pStack->pBottom){
        printf("%d\t",p->data);
        p = p->pNext;
    }
    printf("\n");

    return;
}

/**
    判断栈是否为空
*/
bool isEmpty(PSTACK pStack){
    if(pStack->pBottom == pStack->pTop)
        return true;
    else
        return false;
}


/**
    出栈,并保存出栈元素
*/
bool pop_stack(PSTACK pStack,int *pElement){
    if(isEmpty(pStack)){
        printf("出栈失败!栈为空!");
        return false;
    }
    //定义一个值保存删除的结点
    PNODE p = pStack->pTop;
    *pElement = p->data;
    pStack->pTop = p->pNext;
    free(p);
    p=NULL;

    return true;

}

/**
    清空栈
*/
void clear_stack(PSTACK pStack){
    if(isEmpty(pStack))
        return;

    PNODE p = pStack->pTop;
    PNODE q = NULL;

    while(p != pStack->pBottom){
        q = p->pNext;
        free(p);
        p=q;
    }
    pStack->pTop = pStack->pBottom;
    return;
}

目录
相关文章
|
27天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
123 9
|
18天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
23 1
|
2月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
46 1
|
2月前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
70 4
|
5天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
26 5
|
21天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
24天前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
26天前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
47 4
|
2月前
|
机器学习/深度学习 存储 人工智能
数据结构在实际开发中的广泛应用
【10月更文挑战第20天】数据结构是软件开发的基础,它们贯穿于各种应用场景中,为解决实际问题提供了有力的支持。不同的数据结构具有不同的特点和优势,开发者需要根据具体需求选择合适的数据结构,以实现高效、可靠的程序设计。
75 7
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!