AlgorithmsI PA2: Randomized Queues and Deques Deque

本次作业考察利用array 或者linked list 实现规定时间复杂度的queue 和stack, 不能使用java 自带的stack 和queue. 目的是让我们掌握自己设计的函数的复杂度。

Deque成功的关键是

1. 选择合适的数据结构,本题选择doubly LinkedList.

2. 自己写测试代码,测试各种情况。addLast, removeFirst 等等,尤其注意边界情况。

Java code:

//Deque - should be implemented using a doubly linked list
import edu.princeton.cs.algs4.StdIn; 
import edu.princeton.cs.algs4.StdOut; 
import edu.princeton.cs.algs4.StdRandom;
import java.util.Iterator;
import java.util.NoSuchElementException;

/*The goal of this assignment is to implement data types from first principles, 
 *using resizing arrays and linked lists.
*/
/*
 * A double-ended queue or deque (pronounced "deck") is a generalization of a stack and a queue that 
 * supports adding and removing items from either the front or the back of the data structure. 
 * 
 * Performance requirements.  
 * Your deque implementation must support each deque operation in constant worst-case time.
 * A deque containing N items must use at most 48N + 192 bytes of memory. 
 * and use space proportional to the number of items currently in the deque. 
 * 
 * Additionally, your iterator implementation must support each operation (including construction) in constant worst-case time.
 */
public class Deque<Item> implements Iterable<Item> {
    private int N;             // size of the stack
    private Node first;
    private Node last;
    
    // helper linked list class
    private class Node {
        private Item item;
        private Node prev;
        private Node next;
    }
    
    // construct an empty deque
    public Deque()  {                        
         N = 0;
         first = null;
         last = null;
    }
    
    // is the deque empty?
    public boolean isEmpty()  {               
         return N == 0;
    }
    
    // return the number of items on the deque
    public int size()  {                      
         return N;
    }
    
    //Throw a java.lang.NullPointerException if the client attempts to add a null item
    public void addFirst(Item item)  {        // add the item to the front
        if(item == null) {
            throw new NullPointerException("add a null item");
        }
        Node oldfirst = first;
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        first.prev = null;
        if(isEmpty()) {
           last = first;
        } else {
           oldfirst.prev = first;
        }
        N++;
    }
    
    //Throw a java.lang.NullPointerException if the client attempts to add a null item
    public void addLast(Item item)   {        // add the item to the end
        if(item == null) {
            throw new NullPointerException("add a null item");
        }
        Node oldlast = last;
        last = new Node();
        last.item = item;
        last.next = null;
        last.prev = oldlast;
        if(isEmpty()) {
            first = last;
        }else {
            oldlast.next = last;
        }
        N++;
    }
    
    //remove and return the item from the front
    // throw a java.util.NoSuchElementException if the client attempts to remove an item from an empty deque
    public Item removeFirst()   {            
        if (isEmpty()) {
            throw new NoSuchElementException("Deque underflow"); 
        }
        Item item = first.item; // save item to return
        Node oldfirst = first;
        first = first.next;  // delete first node
        oldfirst = null;
        if(first == null) { 
            last = null;
        } else {
           first.prev = null;
        }
        N--;
        return item;
    }
    
    // remove and return the item from the end
    // throw a java.util.NoSuchElementException if the client attempts to remove an item from an empty deque
    public Item removeLast()   {              
        if (isEmpty()) {
            throw new NoSuchElementException("Deque underflow"); 
        }
        Item item = last.item; //save item to return
        Node oldlast = last;
        last = last.prev;
        oldlast.prev = null;
        
        if(last != null) {
            last.next = null;
        }else {
            first = null;
        }
        oldlast = null;
        N--;
        return item;       
    }
    
    // return an iterator over items in order from front to end
    public Iterator<Item> iterator()   {      
        return new ListIterator();
    }
    
    private class ListIterator implements Iterator<Item> {
        private Node current = first;
        
        public boolean hasNext()  {
            return current != null; 
        }
        public void remove()  { 
            throw new UnsupportedOperationException(); 
        }
        
        public Item next() {
            if (!hasNext()) { 
                throw new NoSuchElementException(); 
            }
            Item item = current.item;
            current = current.next;
            return item;    
        } 
    }
    
    public static void main(String[] args)  { // unit testing
          //testSimpleAddRemove();
          testAddRemoveallItems();
    }
    private static void testSimpleAddRemove() {
        Deque<Integer> d = new Deque<Integer>();
        d.addFirst(10);
        d.addFirst(20);
        d.addFirst(30);
        d.addLast(100);
        d.addLast(101);
        d.addLast(102);
         
        assert d.size() == 6;
        System.out.println(d.size());
        
        Iterator i = d.iterator();
        while (i.hasNext()) {
            System.out.print(i.next() + " ");
        }
        System.out.println("");
        
        System.out.println("d.removeFirst() is " + d.removeFirst());
        System.out.println("d.removeLast() is " + d.removeLast());
        System.out.println(d.size());
        
         i = d.iterator();
        while (i.hasNext()) {
            System.out.print(i.next() + " ");
        }
        System.out.println("");
    }
    
     private static void testAddRemoveallItems() {
        Deque<Integer> d = new Deque<Integer>();

        d.addFirst(10);
        //d.addLast(20);
        
         Iterator i = d.iterator();
        while (i.hasNext()) {
            System.out.print(i.next() + " ");
        }
        System.out.println("");
        System.out.println("d.size is " + d.size());
      //System.out.println("d.removeFirst() is " + d.removeFirst());
        System.out.println("d.removeLast() is " + d.removeLast());
        System.out.println("d.size is " + d.size());
    }
}
原文地址:https://www.cnblogs.com/anne-vista/p/4843186.html