背包,队列,栈的java实现

先从栈开始实现,从简单开始,栈的特点是先进后出LIFO,应该具有的操作有:入栈push 出栈pop,判断栈是否为空isEmpty和返回栈大小size,使用java中最简单的数组实现字符串栈为开始:

public class FixCapacityStringStack{
    private String[] str = null;
    private int n = 0;
    public FixCapacityStringStack(int m){
        str = new String[m];
    }
    public boolean isEmpty(){
        return n == 0;
    }
    public int size(){
        return n;
    }
    public void push(String s){
        str[n++] = s;
    }
    public String pop(){
        return str[--n];
    }
}
这样的字符串栈仅能简单体现栈的基本功能,不可避免的有很多缺陷,首先由于固定类型只能存储字符串对象,其他对象无法复用,应该定义一个所有对象都能通用的通用栈,可以用java的泛型实现:
public class FixCapacityStack <Item>{
    private Item[] stack = null;
    private int N = 0;
    public FixCapacityStack(int m){
        stack = (Item[]) new Object[m];
      //stack = new Item[m];//waring:Cannot create a generic array of Item    
    }
    public boolean isEmpty(){
        return N == 0;
    }
    public int size(){
        return N;
    }
    public void push(Item item){
        stack[N++] = item;
    }
    public Item pop(){
        return stack[--N];//此处对象游离
    }
}
数组实现的泛型定容栈虽然解决了对象通用问题,但很多细节的实现仍然很粗糙,比如数组的大小固定,创建后就无法改变,出栈操作对象游离,虽然对象已出栈,但仍然在数组中,应该不保留出栈对象句柄,让此对象等待垃圾回收等等。
于是我们需要用数组实现一个对所有对象通用,并且能够动态调整数组大小,实现无上界的栈,同时对出栈对象及时消除句柄的栈,另外,作为集合对象类型,这样的栈应该支持迭代遍历栈中所有数据元素。
关于调整数组大小,可以采用这样的方式:
如果入栈后判断数组已满,则创建一个新数组,此数组长度为原数组的两倍,将原数组复制到新数组。
如果出栈后判断栈的长度小于数组长度的四分之一,则将创建新数组为原数组长度的一半,复制原数组到新数组。
如此以数组为原型的栈不会溢出,同时,栈的使用率永远不会低于四分之一,不会造成空间浪费。
如果要迭代遍历集合元素,类似其他集合类实现Iterable接口,实现iterator方法返回迭代器对象,迭代器对象应是一个实现hasNext,next,remove方法,操作栈对象。可以实现为内部类。
import java.util.Iterator;

public class ReizeArrayStack<Item> implements Iterable<Item>{
    private Item[] stack = null;
    private int N = 0;
    public ReizeArrayStack(){
        stack = (Item[])new Object[1];
    }
    public boolean isEmpty(){
        return N == 0;
    }
    public int size(){
        return N;
    }
    public void push(Item item){
        if(N == stack.length){
            resize(2*stack.length);
        }
        stack[N++] = item;
    }
    public Item pop(){
        Item temp =  stack[--N];
        stack[N] = null;//出栈对象及时清除,无引用对象等待回收。
        if(N == stack.length/4){
            resize(stack.length/2);
        }
        return temp;
    }
    public void resize(int max){//重新调整数组大小
        Item[] temp = (Item[])new Object[max];
        for(int i =0;i<N;i++){
            temp[i] = stack[i];
        }
        stack = temp;
    }
    @Override
    public Iterator<Item> iterator() {
        // TODO Auto-generated method stub
        return new ReizeArrayStackIterator();
    }
    private class ReizeArrayStackIterator implements Iterator<Item>{
        private int i = N;
        @Override
        public boolean hasNext() {
            // TODO Auto-generated method stub
            return i > 0;
        }
        @Override
        public Item next() {
            // TODO Auto-generated method stub
            return stack[--i];
        }

        @Override
        public void remove() {
            // TODO Auto-generated method stub
        }
    }
}
如果使用链表实现栈,可以方便的多,链表实现栈达到了最优的设计目的:
可以处理任何数据类型;
所需空间和集合大小成正比;
操作所需的时间和集合的大小无关;(因为总是表头插入删除)
import java.util.Iterator;
public class ListStack<Item> implements Iterable<Item> {
    public Node first;
    public int N = 0;
    private class Node{
        public Item item;
        public Node next;
    }
    public boolean isEmpty(){
        return N == 0;
    }
    public int size(){
        return N ;
    }
    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;
    }
    @Override
    public Iterator<Item> iterator() {
        // TODO Auto-generated method stub
        return null;
    }
    private class ListStackIterator implements Iterator<Item>{
        private Node current = first;
        @Override
        public boolean hasNext() {
            // TODO Auto-generated method stub
            return current != null;
        }

        @Override
        public Item next() {
            // TODO Auto-generated method stub
            Item temp = current.item;
            current = current.next;
            return temp;
        }
        public void remove() {}   
    }
}
队列的链表实现也如此类似(FIFO):
public class ListQueue <Item>{
    private Node first = null;
    private Node last = first;
    private int N = 0 ;
    private class Node{
        public Item item;
        public Node next;
    }
    public boolean isEmpty(){
        return first == last;
    }
    public int size(){
        return N;
    }
    public void enqueue(Item item){
        last = new Node();
        last.item = item;
        last.next = null;
        last = last.next;
        N++;
    }
    public Item dequeue() {
        if (!isEmpty()) {
            Item temp = first.item;
            first = first.next;
            N--;
            return temp;
        }
        else return null;
    }
}
背包是一种不支持从中删除元素的集合数据类型,目的是帮助用例收集数据元素,并迭代遍历所有收集到的元素,迭代顺序不确定。用例可以检查背包是否为空或者获取背包中元素的数量。
import java.util.Iterator;

public class ListBag <Item> implements Iterable<Item>{
    private Node first;
    private class Node{
        Item item;
        Node next;
    }
    public void add(Item item){
        Node oldfirst = first;
        first = new Node();
        first.item = item;
        first.next = oldfirst;
    }
    @Override
    public Iterator<Item> iterator() {
        // TODO Auto-generated method stub
        return new ListBagIterator();
    }
    private class ListBagIterator implements Iterator<Item>{
        private Node current = first;
        @Override
        public boolean hasNext() {
            // TODO Auto-generated method stub
            return current == null;
        }
        @Override
        public Item next() {
            // TODO Auto-generated method stub
            Item temp = current.item;
            current = current.next;
            return temp;
        }
        @Override
        public void remove() {}
       
    }
}

原文地址:https://www.cnblogs.com/brucemu/p/3113451.html