【数据结构】栈(C++ )

简介: 【数据结构】栈(C++ )

@TOC

只能在一边进出,先进的后出。

进出的一端叫做栈顶,另一端叫做栈底。

栈可以使用顺序存储结构,也能使用链式存储结构。


注意:栈只能在一端进行操作,这是栈的关键特征,也就是说栈不允许在中间进行查找、插入、删除等操作,(但是在实际应用中我们可以打破它)。

这里掌握初始化、入栈、出栈、取栈顶元素操作即可。

顺序存储结构实现栈

#include<iostream>
using namespace std;

#define MAX_SIZE 128
typedef int DataType;

//栈的结构有多重方式定义,不用局限于这一种
/*
    例如:
        定义两个int型,并且直接开辟好数组空间
        定义一个指针,一个int top
*/
typedef struct _Stack
{
    DataType* top;    //栈顶指针
    DataType* base;//栈底指针
    //其实没有必要定义一个来标记元素的个数。
    //两个指针指向同一个数组,他们两个相减得到是中间元素的个数。
    //否则两个地址相减没有意义
}Stack;

//栈的初始化
bool initStack(Stack& S)
{
    //先用栈底指针来拿到这个刚开辟好空间的数组
    S.base = new int[MAX_SIZE];//指针来定位这个数组
    if (!S.base)
    {
        return false;
    }
    S.top = S.base;
    return true;
}

//入栈
bool pushStack(Stack& S, DataType data)
{
    if (!S.base)
    {
        return false;
    }
    if (S.top - S.base == MAX_SIZE)
    {
        //栈满
        return false;
    }

    //栈中还有空位置
    *(S.top) = data;
    S.top++;
    return true;
}

//出栈-栈顶元素出栈
DataType popStack(Stack& S)
{
    //不为空
    if (S.top != S.base)
    {
        return *(--S .top);
    }
    else
    {
        return -1;
    }
}
//返回栈顶元素         
DataType getTop(Stack& S)
{
    if (S.top - S.base == 0)
    {
        return -1;
    }
    return *(S.top-1);
}
int main(void)
{
    Stack S;
    initStack(S);    
    int n = 0;
    int m = 0;
    cin >> n;
    m = n;
    while (n)
    {    
        pushStack(S, n);
        n--;
    }
    cout << "____" << endl;
    cout << getTop(S) << endl;
    cout << "____" << endl;
    while (m)
    {
        cout << popStack(S) << endl;
        m--;
    }
    return    0;
}

入栈操作图示:

在这里插入图片描述

链接存储结构实现栈

#include<iostream>
using namespace std;

//数据类型
typedef int DataType;
//最大存储数量
#define  MAX_SZIE 128
//结点结构
typedef struct _Snode
{
    DataType data;
    struct _Snode* next;
}Snode;

//栈(头)结构
typedef struct _Stack
{
    int count;
    Snode* base;
    Snode* top;
}Stack;

//初始化
bool initStack(Stack* S)
{
    if (!S)
    {
        return false;
    }
    S->base = S->top = NULL;
    S->count = 0;
    return true;
}

//入栈
bool pushStack(Stack* S, Snode* node)
{
    if (!S || !node)
    {
        return false;
    }

    //第一次插入元素
    if (S->count == 0)
    {
        S->base = S->top = node;
        S->top->next = NULL;
        S->count++;
    }
    else
    {
        S->top->next = node;
        S->top = node;
        S->count++;
    }
    return false;
}
//出栈
bool popStack(Stack* S)
{
    if (!S || S->count == 0)
    {
        return false;
    }
    Snode* tempnode = S->base;

    while (tempnode->next != S->top && S->count != 1)
    {
        tempnode = tempnode->next;
    }
    if (S->count == 1)//如果栈中只剩下一个结点可以删除
    {
        S->base = NULL;
    }
    //现在tempnode是top的前一个结点
    delete S->top;
    S->top = tempnode;//如果是最后一个结点的话base和top都被置空了
    S->top->next = NULL;
    
    S->count--;
    return true;
}
//拿到栈顶元素
bool getTop(Stack* S,DataType* m_data)
{
    if (!S || S->count == 0)
    {
        return S;
    }
    *m_data = S->top->data;
    return false;
}
//判断栈是否为空
bool isEmpty(Stack* S)
{
    if (S->count == 0)
    {
        return true;
    }
    return false;
}
int main(void)
{
    Stack* S = new Stack;
    initStack(S);

    int n = 5;
    int m = n;
    while (n)
    {
        Snode* tempnode = new Snode;
        tempnode->data = n;
        pushStack(S, tempnode);
        n--;
    }

    while (m >0)
    { 
        m--;
    }

    cout << S->top->data << " ";
    popStack(S);

    cout << S->top->data << " ";
    popStack(S);

    cout << S->top->data << " ";
    popStack(S);
    
    cout << S->top->data << " ";
    popStack(S);

    cout << S->top->data << " ";
    popStack(S);

    if (!isEmpty(S))
    {
        cout << S->top->data << " ";
    }


    int temp = 0;
    getTop(S, &temp);
    cout << temp << endl;

    delete S;
    return    0; 
}

补充:要修改指针指向地址,可以传递二级指针。

一级指针修改值。

实际应用

迷宫求解

链接——【栈】实现迷宫求解(C++)(详解)

表达式求值

链接——【数据结构】栈(C++)

相关文章
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
161 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
30 1
|
19天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
42 5
|
1月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
1月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
1月前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
51 4
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
43 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
26天前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
42 0
|
2月前
初步认识栈和队列
初步认识栈和队列
61 10