堆栈的两种实现方式

来源:互联网 发布:云计算开发语言 编辑:程序博客网 时间:2024/06/06 00:39

两种堆栈的实现方式,可变数组和链表


数组实现

要实现堆栈这样的数据结构,我们需要满足以下的API

  • API
    void push(Item item)
    Item pop()
    boolean isEmpty()
    int size()

由于JAVA中数组的大小一旦固定就不能再次改变,而堆栈的大小是不能确定的,所以我们还要满足数组大小动态变化的要求

  1. 当堆栈大小达到预设大小的时候将其大小加倍
  2. 当堆栈大小达到预设大小的 1/4 的时候将堆栈大小改为一半

    代码如下

package Fundamental;import java.util.Iterator;public class ResizingArrayStack<Item> implements Iterable<Item>{    private int N=0;    private Item[] a= (Item[])new Object[1];    public int size()                       {return N;}    public boolean isEmpty()        {return N==0;}    private void resize(int max){        Item[] temp=(Item[]) new Object[max];   //创建泛型数组        for(int i=0;i<N;i++)            temp[i]=a[i];        a=temp;  //将原数组复制到一个新数组    }    public void push(Item item){        if(N==a.length)   //先判断堆栈是否占满了数组,如果满了则将大小加倍            resize(a.length*2);        a[N++]=item;  //注意这里赋值以后指针又向后移动了一次    }    public Item pop(){        Item item=a[--N];   //与上面的N++相对应        a[N]=null;   //这里是防止对象游离,手动置NULL        if(N==a.length/4)            resize(a.length/2);        return item;    }    @Override    public Iterator<Item> iterator() {   //实现了Iterable接口,重写接口里面的方法        return new ReverseArrayIterator() ;   //传入一个继承了Iterator的对象    }    private class ReverseArrayIterator implements Iterator<Item>{        int i=N;        @Override        public boolean hasNext() {            return i>0;        }        @Override        public Item next() {            return a[--i];        }    }} 

链表实现

API同上,链表的增加与删除操作相对于数组更为快速,并且大小是动态变化的,增删操作都在表头进行较为便捷。

链表表头增加节点与删除节点的代码实现如下

class Node{    Item item;    Node next;}//------------------------------------//在表头增加节点oldfirst=first; //先保留截断的部分Node first=new Node();  //为新的表头创建新的节点first.item=item;    //为新创建的节点赋值first.next=first;   //将其指针指向保存下来的旧节点//------------------------------------//删除表头first=first.next;   //这样原表头就变成了游离的垃圾

整体代码实现

package Fundamental;import java.util.Iterator;public class LinkStack<Item> implements Iterable<Item>{    private class Node{        Item item;        Node next;    }    private Node first=new Node();   //创建一个新表头    private int N=0;   //计数    public void push(Item item){   //添加一个新的表头并计数        Node oldfirst=first;        first=new Node();        first.item=item;        first.next=oldfirst;        N++;    }    public Item pop(){   //删除表头        Item temp=first.item;        first=first.next;        N--;        return temp;    }    public int size(){        return N;    }    public boolean isEmpty(){        return first==null;    }    @Override    public Iterator<Item> iterator() {        return null;    }    private class ReverseNodeIterator implements Iterator<Item>{        Node temp=first;   //临时节点存储表头        @Override        public boolean hasNext() {            return temp!=null;        }        @Override        public Item next() {    //相当于就是弹栈,但是并没有删除,只是遍历了其中的元素            Item item=temp.item;            first=temp.next;            return item;        }    }}