数据结构链表的初始化插入删除_先进后出的数据结构——栈

bde58075846f317d3d6563d8c2a66746.png

一、栈的概述

和队列一样,栈是一种操作受限的线性表,和队列不同的是栈只允许从一端插入和删除数据。

因此,栈的特点是:

  • 栈中的数据元素遵守“先进后出"(First In Last Out)的原则,简称FILO结构。
  • 限定只能在栈顶进行插入和删除操作,栈最重要的特征

一些需要了解的概念:

栈顶与栈底:允许元素插入与删除的一端称为栈顶,另一端称为栈底。

压栈:栈的插入操作,叫做进栈,也称压栈、入栈。

弹栈:栈的删除操作,也叫做出栈。

aea369e3da67caaadd1535935543c050.png

就像生活中我们取放盘子,当一摞盘子在桌子上时候,我们总是会取最上边的盘子,同时,我们在放盘子时,也会放在最上面。其实,每个栈都有一个栈顶指针,它初始值为-1,且总是指向最后一个入栈的元素,栈有两种处理方式,即进栈(push)和出栈(pop),因为在进栈只需要移动一个变量存储空间,所以它的时间复杂度为O(1),但是对于出栈分两种情况,栈未满时,时间复杂度也为O(1),但是当栈满时,需要重新分配内存,并移动栈内所有数据,所以此时的时间复杂度为O(n)。

栈有两种存储方式,即线性存储和链接存储(链表)。

二、栈的常用操作和实现

栈的常用操作有:

  • pop弹栈,向栈底添加一个元素
  • pop 压栈,从栈顶取出一个元素
  • size 判定栈中所含元素的个数
  • isEmpty 判断栈是否为空
  • peek 获取栈顶元素的值,复制栈顶元素返回,但不进行删除

1、线性存储
线性存储的方式和线性表基本一致,不同的是添加了后进先出的限制,并且是静态分配的,即使用前,它的内存就已经以数组的形式分配好了,所以在初始化时,需要指明栈的节点最大个数。基于数组的栈是以数组为底层数据结构的,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向。

public class MyStack {  //大小  private int size;    //栈的最大容量  private int maxSize;    //默认最大容量10  private static final int DEFAULT_MAX_SIZE =10;/数组(用来保存数据)String[] stack;                                                             //有参初始化,设置栈的最大容量                               public MyStack(int maxSize) {                                      this.maxSize=maxSize;                                      stack =new String[maxSize];                               }                                                             //无参初始化,设置栈的默认容量                               public MyStack() {                                      this(DEFAULT_MAX_SIZE);                               }                                                             //进行入栈操作                               public void push(String s) {                                      if(size >=  maxSize) {                                              throw new IndexOutOfBoundsException("栈已经满了!");                                      }                                      stack[size] =s;                                      size++;                                      look();                               }                                                             //出栈操作                               public String pop() {                                      String rs=stack[size-1];                                      //从后往前将做高位的值赋为null                                      stack[size-1]=null;                                      size--;                                      look();                                      return rs;                               }                                                             //清栈操作                               public void clear() {                                      for(int i=0;i

2、链接存储
对于单链表类,只要做适当的修改,限制其插入、删除、修改和访问结点的行为,使其符合栈先进后出的规则即可,另外需要单独提供栈访问的接口函数,例如进栈、出栈、获取栈大小等。基于单链表的栈是以链表为底层的数据结构的,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部

/ * 栈的实现 * */public class MyStackNode {                               //大小                               private int size;                               //栈的最大容量                               private int maxSize;                               //默认最大容量10                               private static final int DEFAULT_MAX_SIZE =10;                               //栈顶的节点                               private Node top;                                                             //有参初始化,设置栈的最大容量                               public MyStackNode(int maxSize) {                                      this.maxSize=maxSize;                               }                                                             //无参初始化,设置栈的默认容量                               public MyStackNode() {                                      this(DEFAULT_MAX_SIZE);                               }                                                             //进行入栈操作                               public void push(String s) {                                      if(size >=  maxSize) {                                              throw new IndexOutOfBoundsException("栈已经满了!");                                      }                                      Node node=new Node(s,top);                                      top=node;                                      look();                                      size++;                               }                                                             //移除栈顶的元素                               public String pop() {                                      if(top == null)                                              return null;                                      Node oldTop=top;                                      Node newTop=top.next;                                      String rs=oldTop.s;                                      oldTop.next=null;                                      oldTop.s=null;                                      oldTop=null;                                      top=newTop;                                      look();                                      size--;                                      return rs;                               }                                                             //清栈操作                               public void clear() {                                      Node node=top;                                      while(node !=null) {                                              Node newTop=node.next;                                              node.next=null;                                              node.s=null;                                              node =newTop;                                      }                                      look();                                      size =0;                               }                                                             //添加一个Node内部类                               class Node{                                      public String s;                                      public Node next;                                                                           public Node(String s,Node next) {                                              this.s=s;                                              this.next=next;                                      }                                                                           public void setNext(Node next) {                                              this.next=next;                                      }                               }                                                             //获取栈的长度                               public int getSize() {                                      return size;                               }                                                             //动态显示栈中的数据                               private void look() {                                      System.out.println("");                                      Node node=top;                                      while(node !=null) {                                              System.out.print(node.s + " ");                                               node=node.next;                                      }                               }                               public static void main(String[] args) {                                      MyStackNode stack=new MyStackNode(4);                                      //MyStack stack=new MyStack();                                      stack.push("壹");                                      stack.push("贰");                                      stack.push("叁");                                      stack.push("肆");                                      stack.pop();                                      stack.pop();                                      stack.push("money");                                      stack.push("money");                                      System.out.println("当前栈的容量为:" + stack.getSize());                                      stack.clear();                               }}测试:

三、栈的应用场景

  • 数制转换
  • 字符匹配
  • 数据反转
  • 括号匹配检验
  • 平衡符号的判断

四、栈和队列的区别

栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。

栈是先进后出,队列是先进先出。

栈只允许在表尾一端进行插入和删除,队列只允许在表尾一端进行插入,在表头一端进行删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值