c++实现stack_c语言输出栈中所有元素

c++实现stack_c语言输出栈中所有元素栈是数据结构中较为简单的结构体,是一种操作收到限制的线性表.但简单不代表没用,毕竟数组还贼简单呢.谁敢说数组没用?栈栈的理论栈是一个先进后出的结构,类似于堆盘子,先放到地上的盘子最后被取走(默认只能取走一个盘子)栈其实就是操作受限的线性表,只有一个口,每一次操作时,这个口可以当出口也可以当入口.例如:水桶,注入水时,水桶的头当做入口,倒水时,水桶的头当做出口栈的图解.在图解之前,先举一个例…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

2022/8/10 说明: 评论区有很多反对的声音, 有说我写错的, 有说我用了C++的, 大家可以自己多尝试下, 截至2022/8/10的反馈我都看过了, 目前都没问题.
2019/5/22 更新,将颠倒的Push和Pop方法更正,并更换图片。
栈是数据结构中较为简单的结构体,是一种操作收到限制的线性表.但简单不代表没用,毕竟数组很简单.但谁敢说数组没用呢?

栈的理论

  • 栈是一个先进后出的结构,类似于堆盘子,先放到地上的盘子最后被取走(默认只能取走一个盘子)
  • 栈其实就是操作受限的线性表,只有一个口,每一次操作时,这个口可以当出口也可以当入口.
  • 例如:水桶,注入水时,水桶的头当做入口,倒水时,水桶的头当做出口

栈的图解.

在图解之前,先举一个例子,让大家记住栈 : 栈其实就是吃了一顿饭,然后吐出来.

  • 这是一个空栈,只有上面是入口和出口
    在这里插入图片描述

  • 放入一个元素a

在这里插入图片描述

  • 接着依次放入B,C元素

在这里插入图片描述

  • 取出一个元素,由栈只有一个口的特点可以知道取出了C

在这里插入图片描述

  • 再次放入一个元素D

在这里插入图片描述

栈的可用操作

根据理论环节,可以轻易的看出:栈的基本操作只有两个:

  • 入栈
  • 出栈

而且样子长得十分像一个水桶。

但是如果栈已经放满了,就像水桶装满了水一样,不能再放水了,即不能再进行入栈操作,所以要在每次入栈前判断栈满的情况.同理,出栈之前,栈中必须有数据,不然就出现要么空指针,要么野指针.都不是我们想要的结果,所以出栈前要判断栈空,.
所有一个栈一共有四个功能:

  • 入栈(英文名:push)
  • 判(栈)满(isFull)
  • 出栈(pop)
  • 判(栈)空(isEmpty)

栈的C语言定义(结构体)

开篇就说了栈是操作收到限制的线性表,而众所周知的线性表主要有:
1.顺序存储的数组,
优点: 节省空间, 操作简单,学习成本较低,易于理解.
缺点: 栈的大小一开始就声明’死’了,不利于使用.
2.非顺序存储的链表.
优缺点:与数组栈正好相反.

两种栈各有好处,争论是愚蠢的,学习是学不完的,所以赶快开始coding吧

数组栈

数组栈,顾名思义,就是基于数组的栈,也是说把一个数组的强大的下标功能阉割掉,并且只能从一头进入(数组头明显更为方便)
所以结构体为:
(为了方便学习,存储类型统一使用int,但是我们一般更习惯在头文件下面给int 起一个别名,原因很简单:这样就这样实现简单的多态,需要将int类型栈改成char类型栈时,只需要改定义的别名中的类型即可)

typedef struct
{ 
   
    int Data[MaxSize];   // 存储元素的数组
    int topIdx;       //栈顶指针
}SeqStack;

栈的四个基本操作定义:

//return 0 为false,1为true(下同)
// 将元素推入栈中
int Push(SeqStack &L, int e)
{ 
    // 栈已满
	if(L.topIdx==MaxSize -1)
    { 
   
        return 0;
    }
    // 加入栈中
    L.Data[L.topIdx++] = e;
    // 返回自身
    return e;
}
// 移除栈顶元素
int Pop(SeqStack &L)
{ 
   	// 栈空
     if(L.topIdx == 0)
    { 
   
         //返回失败
         return 0;
    }
    // 打印并返回栈
    int val = L.Data[--L.topIdx];
    printf("%d ",val);
    return val;
}
//判断栈s是否为空
int isEmpty(SeqStack s)
{ 
   
    // 如果下标在0,说明栈中无元素
    if(s.topIdx != 0)
    { 
   
        return 1;
    }
    return 0;
}
// 判断栈是否已栈.
Status isFull(SeqStack s)
{ 
   
    // 已满返回true(1)
    if(s.topIdx != MaxSize -1)//之前的定义数组的最大值的下标
    { 
   
        return 1;
    }
    return 0;
}

链表栈

结构体

typedef struct LNode
{ 
   
    ElemType data;
    struct LNode * next;
} LNode,*LinkList;

两大功能(链表无需判满,判空也简单,不再单独实现)

Status Pop(LinkList L)
{ 
   
    if(L->next == NULL)
    { 
   
        return 0;
    }
    LinkList tem = L->next;
    printf("%d ",tem->data);
    L->next = tem->next;
    free(tem);
    return 1;
}
Status Push(LinkList L, ElemType e)
{ 
   
    LinkList newNode = (LinkList) malloc(sizeof(LinkList));
    newNode->data = e;
    newNode->next = L->next;
    L->next = newNode;
    return 1;
}

最后写几个简单的作业(我们老师留给我们的)以及我的代码

//1、本题要求实现顺序栈,写出Push 、Pop、StackEmpty函数的实现,并用一个简单的main函数测试。

//已有类型定义
typedef struct
{ 
   
    ElementType Data[MaxSize];   // 存储元素的数组
    Position Top;       //栈顶指针
}SeqStack;

//函数接口定义:
Status Push(SeqStack &L, ElemType e);
Status Pop(SeqStack &L, ElemType &e);
Status StackEmpty(SeqStack s);  //判断栈s是否为空
//其中 L 和 e 都是用户传入的参数。 L 是带头结点的头指针; e 是数据元素。
/** * 3、进制转换。 * 输入一个十进制正整数n和一个目标进制R(1<R<10),将n转换为R进制。要求不使用递归或数组,而使用第1题* 或第2题中定义的栈来实现。 */ 

我的代码实现:

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
typedef int Status;
typedef int ElemType;
typedef int Position;
//1、本题要求实现顺序栈,写出Push 、Pop、StackEmpty函数的实现,并用一个简单的main函数测试。
//已有类型定义
typedef struct
{ 
   
    ElemType Data[MaxSize];   // 存储元素的数组
    Position Top;       //栈顶指针
} SeqStack;

//函数接口定义:
Status Push(SeqStack &L,ElemType e);
Status Pop(SeqStack &L);
Status StackEmpty(SeqStack s);  //判断栈s是否为空
Status prinStack(SeqStack &L);
Status convNum(int n, int R);
Status pipei();
void work1();
//其中 L 和 e 都是用户传入的参数。 L 是带头结点的头指针; e 是数据元素。
int main()
{ 
   
    //work1();//第一题
    //convNum(8,2);//进制转化
    pipei();
    return 0;
}
Status prinStack(SeqStack &L)
{ 
   
    while (StackEmpty(L))
    { 
   
        Push(L);
    }
    return 1;
}
void work1()
{ 
   
    SeqStack L;
    L.Top = 0;
    Pop(L, 1);
    Pop(L, 2);
    Pop(L, 3);
    prinStack(L);
}
Status Pop(SeqStack &L)
{ 
   
if(L.Top == 0)
    { 
   
        return 0;
    }
    printf("%d ",L.Data[--L.Top]);
    return 1;
}
Status Push(SeqStack &L, ElemType e)
{ 
   
        if(L.Top==MaxSize -1)
    { 
   
        return 0;
    }
    L.Data[L.Top++] = e;
    return 1;
}
//判断栈s是否为空
Status StackEmpty(SeqStack s)
{ 
   
    if(s.Top != 0)
    { 
   
        return 1;
    }
    return 0;
}
//3、进制转换。
//输入一个十进制正整数n和一个目标进制R(1<R<10),将n转换为R进制。要求不使用递归或数组,而使用第1题或第2题中定义的栈来实现。
Status convNum(int n, int R)
{ 
   
    //声明栈
    SeqStack L;
    L.Top = 0;
    while (n!=0)
    { 
   
        //将每次产生的余数防入栈低
        Pop(L, n%R);
        n/=R;
    }
    prinStack(L);
    return 1;
}

以下附上Java 代码实现的栈

public class LinkedStack<T> { 
   
    private Node topNode;

    public T push(T newEntry) { 
   
        Node newNode = new Node<T>(newEntry, topNode);
        topNode = newNode;
        T tempData = peek();
        return tempData;
    }

    public T pop() { 
   
        T tempData = peek();
        if (tempData == null) { 
   
            return null;
        }
        topNode = topNode.next;
        return tempData;
    }

    public T peek() { 
   
        if (isEmpty()) { 
   
            return null;
        }
        return (T) topNode.data;
    }

    public boolean isEmpty() { 
   
        return topNode == null;
    }

    public void clear() { 
   
        topNode = null;
        // java拥有内存回收,只需要让头结点引用为空即可,GC就可以回收掉所有其他节点。
    }

    public LinkedStack() { 
   
        this.topNode = null;
    }

    private class Node<T> { 
   
        private T data;
        private Node next;

        public Node(T dataPortion) { 
   
            this(dataPortion, null);
        }

        public Node(T data, Node next) { 
   
            super();
            this.data = data;
            this.next = next;
        }

        public T getData() { 
   
            return data;
        }

        public void setData(T data) { 
   
            this.data = data;
        }

        public Node getNext() { 
   
            return next;
        }

        public void setNext(Node next) { 
   
            this.next = next;
        }

    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196742.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Rectified Linear Unit_激活函数图像

    Rectified Linear Unit_激活函数图像传统Sigmoid系激活函数传统神经网络中最常用的两个激活函数,Sigmoid系(Logistic-Sigmoid、Tanh-Sigmoid)被视为神经网络的核心所在。从数学上来看,非线性的Sigmoid函数对中央区的信号增益较大,对两侧区的信号增益小,在信号的特征空间映射上,有很好的效果。从神经科学上来看,中央区酷似神经元的兴奋态,两侧区酷似神经元的抑制态,因而在

    2025年6月30日
    2
  • 生产环境 Kubernetes 中出现了很多 Evicted Pod,我该怎么办呢?

    生产环境 Kubernetes 中出现了很多 Evicted Pod,我该怎么办呢?公众号关注「奇妙的Linux世界」设为「星标」,每天带你玩转Linux!线上被驱逐实例数据最近在线上发现很多实例处于Evicted状态,通过podyaml可以看到实例是…

    2022年5月17日
    24
  • Qml异步加载图片「建议收藏」

    Qml异步加载图片「建议收藏」当图片很大时,加载图片可能导致UI线程的阻塞,为了确保图片在加载过程中不会阻塞UI线程,将Image元素的’asynchronous’设置为trueImage{asynchronous:truesource:"test.png"}…

    2025年8月8日
    3
  • 12.推荐几款好用的搜索引擎「建议收藏」

    12.推荐几款好用的搜索引擎「建议收藏」1.多吉搜索https://www.dogedoge.com/多吉搜索是我接触的第一款无广告,无跟踪的搜索引擎,网上有它和谷歌搜索的对比,个人认为非常好用,但是最近好像用不了,总显示502badgateway,估计是被人攻击了。。。2.goobehttps://goobe.io/专为程序员设计的搜索引擎(搜索非技术相关的东西也很6),界面是这样事儿的而且可以通过快照访问stackoverflow和github,非常好用无广告,不跟踪3.萌搜http..

    2022年5月23日
    68
  • 智能小车设计规划_智能循迹避障小车设计

    智能小车设计规划_智能循迹避障小车设计摘要该课题主要基于单片机的循迹、避障、WiFi、蓝牙等功能的智能小车,在一些特殊环境下有着特殊的意义。硬件控制以arduino为控制核心。采用超声波避障和红外避障传感器共同完成寻迹、避障功能,并将相关信号传送给单片机,经单片机控制系统分析判断后控制驱动芯片驱动直流电机实现小车前进、后退、左转、右转,停止。软件采用移植性较好的c语言编写,通过手机蓝牙App实现对智能小车的控制。通过TCP/UD协…

    2022年10月18日
    2
  • phpstorm2021.5.1激活码[在线序列号]「建议收藏」

    phpstorm2021.5.1激活码[在线序列号],https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月19日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号