线性结构的应用-栈

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

定义

  • 栈是一种运算受限的线性表
  • 其限制是仅允许在表的一端进行插入和删除运算
  • 允许进行操作的一端被称为栈顶,另一端则称为栈底
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;
}

目录
相关文章
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
287 9
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
44 1
|
13天前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
130 77
|
3月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
58 1
|
3月前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
101 4
|
13天前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
35 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
13天前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
36 9
|
13天前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
29 7
|
3月前
|
机器学习/深度学习 存储 人工智能
数据结构在实际开发中的广泛应用
【10月更文挑战第20天】数据结构是软件开发的基础,它们贯穿于各种应用场景中,为解决实际问题提供了有力的支持。不同的数据结构具有不同的特点和优势,开发者需要根据具体需求选择合适的数据结构,以实现高效、可靠的程序设计。
247 63
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
89 5

热门文章

最新文章