美文网首页程序员
数据结构——栈

数据结构——栈

作者: 我哈啊哈啊哈 | 来源:发表于2018-06-28 20:14 被阅读79次

目录

1、定义

2、实现

2.1 简单数组实现

2.1.1 代码实现
2.1.2 性能和局限性

2.2 动态数组实现

2.2.1 代码实现
2.2.2 性能

2.3 链表实现

2.3.1 代码实现
2.3.2 性能

2.4 基于数组实现和基于链表实现的比较

2.4.1 基于数组实现的栈
2.4.2 基于链表实现的栈

正文

1、定义

栈是一个有序线性链表,只能在表的一端(称为栈顶,top)执行插入和删除。

  • 入栈(push),表示在栈中插入一个元素。
  • 出栈(pop),表示从栈中删除一个元素。
  • 下溢(underflow),试图对一个空栈执行出栈操作。
  • 溢出(overflow),试图对一个满栈执行入栈操作。


    图1-1 例子

2、实现

有以下三种常见的实现方法:

  • 基于简单数组的实现方法
  • 基于动态数组的实现方法
  • 基于链表的实现方法

2.1 简单数组实现

如下图所示,从左至右向数组添加所有元素,并定义一个变量来记录数组当前栈顶(top)元素的下标。


图2-1 简单数组实现
2.1.1 代码实现
public class ArrayStack {
    private int top;
    private int capacity;
    private int[] array;

    //初始化
    public ArrayStack(){
        capacity=5;
        array=new int[capacity];
        top=-1;
    }

    //是否下溢
    public boolean isEmpty(){
        return (top==-1);
    }

    //是否溢出
    public boolean isStackFull(){
        return (top==capacity-1);
    }

    //入栈
    public void push(int data){
        if(isStackFull()){
            System.out.print("溢出");
        }else {
            array[++top]=data;
        }
    }

    //出栈
    public int pop(){
        if(isEmpty()){
            System.out.print("下溢");
            return 0;
        }else {
            return(array[top--]);
        }
    }

    //大小
    public int size(){
        return capacity;
    }

    //销毁
    public void deleteStack(){
        top=-1;
    }
}
2.1.2 性能和局限性
  • 性能:假设n为栈中元素的个数,下图为各算法的时间复杂度。


    图2-2 性能
  • 局限性:栈的最大空间必须预先声明且不能改变,试图对一个满栈执行入栈操作将报溢出异常。

2.2 动态数组实现

上述存在的问题是在固定大小的数组中,如何处理所有空间都已经保存了栈元素这种情况呢?可以使用重复倍增技术来提高性能,如果数组空间已满,新建一个比原来数组空间大一倍的新数组,然后复制元素。

2.2.1 代码实现
public class DynArrayStack {
    private int top;
    private int capacity;
    private int[] array;

    //初始化
    public DynArrayStack(){
        capacity=5;
        array=new int[capacity];
        top=-1;
    }

    //是否下溢
    public boolean isEmpty(){
        return (top==-1);
    }

    //是否溢出
    public boolean isStackFull(){
        return (top==capacity-1);
    }

    //入栈
    public void push(int data){
        if(isStackFull()){
            doubleStack();
        }
        array[++top]=data;
    }

    //出栈
    public int pop(){
        if(isEmpty()){
            System.out.print("下溢");
            return 0;
        }else {
            return(array[top--]);
        }
    }

    //倍增
    private void doubleStack(){
        int newArray[]=new int[capacity*2];
        System.arraycopy(array,0,newArray,0,capacity);
        capacity=capacity*2;
        array=newArray;
    }

    //销毁
    public void deleteStack(){
        top=-1;
    }
}
2.2.2 性能

假设n为栈中元素的个数,下图为各算法的时间复杂度。


图2-3 性能

2.3 链表实现

通过在链表的表头插入元素的方式实现push操作,删除链表的表头结点(栈顶结点)实现pop操作。


图2-4 链表实现
2.3.1 代码实现
public class LLStack {
    private ListNode headNode;

    //初始化
    public LLStack(){
        this.headNode=null;
    }

    //入栈
    public void push(int data){
        if(headNode==null){
            headNode=new ListNode(data);
        }else{
            ListNode llNode=new ListNode(data);
            llNode.setNext(headNode);
            headNode=llNode;
        }
    }

    //栈顶元素
    public int top(){
        if(headNode==null){
            return -1;
        }else {
            return (headNode.getData());
        }
    }

    //出栈
    public int pop(){
        if(headNode==null){
            return -1;
        }else {
            int data=headNode.getData();
            headNode=headNode.getNext();
            return data;
        }
    }

    //是否下溢
    public boolean isEmpty(){
        if(headNode==null){
            return true;
        }else {
            return false;
        }
    }

    //销毁
    public void deleteStack(){
        headNode=null;
    }
}
2.3.2 性能

假设n为栈中元素的个数,下图为各算法的时间复杂度。


图2-5 性能

2.4 基于数组实现和基于链表实现的比较

2.4.1 基于数组实现的栈
  • 各个操作都是常数时间的开销。
  • 每隔一段时间倍增操作的开销较大。
  • n个操作的任意序列的平摊时间开销为O(n)。
2.4.2 基于链表实现的栈
  • 栈规模的增加和减少都很简洁。
  • 各个操作都是常数时间开销。
  • 每个操作都需要使用额外的空间和时间开销来处理指针。

相关文章

  • 栈和队列

    1、栈 栈是一种先进先出的数据结构。栈顶进栈,栈顶出栈。 数据结构 栈的初始化 进栈 出栈 栈的最小值 2、队列 ...

  • 004 go语言实现栈

    1 数据结构 数据结构: 要实现的功能:0 栈的初始化1 获取栈长度2 入栈3 出栈4 清空栈内容5 判断栈是否为...

  • java高级知识点

    1.数据结构 程序=数据结构+算法 栈:后进先出,线性结构 入栈:push 出栈:pop假如已知入栈顺序是ab...

  • 栈和堆以及栈区和堆区的区别

    栈和堆以及栈区和堆区的区别 数据结构中的栈和堆 栈:具有先进后出性质的数据结构 堆:一种经过排序的树形数据结构,节...

  • 数据结构与算法 第二节:栈 栈: 一种先进后出的数据结构。可以想象成手枪的弹夹。 栈的特点: 栈的行为: 栈的代...

  • 2019-07-11—栈

    栈:Java数据结构和算法(四)——栈 string和char一般这么转化: 21、定义栈的数据结构,请在该类型中...

  • 什么是堆栈?

    堆与栈是两种数据结构,并不是一种数据结构,堆是堆,栈是栈。 1、栈:是一种只能在一端进行插入和删除的数据结构。 允...

  • 05--栈 递归

    栈 栈(Stack)又名堆栈,它是一种重要的数据结构。从数据结构角度看,栈也是线性表,其特殊性在于栈的基本操作是线...

  • 18-04-21 python3 算法笔记 002基本数据结构

    线性数据结构 栈,队列,deques,列表其元素在数据结构中的位置由它被添加时的顺序决定。 栈 后进先出栈 LI...

  • 数据结构

    数据结构:要写!!手动!!数据结构非常简洁才可 栈 eg. 弹栈压栈的过程 链表 就是原型链不断的连接,要断去某个...

网友评论

    本文标题:数据结构——栈

    本文链接:https://www.haomeiwen.com/subject/xmopyftx.html