Doubly linked list的java实现

  1package list;
  2
  3import java.io.*;
  4import java.util.*;
  5
  6/**
  7 * <p>
  8 * The <code>List</code> interface is designed to be used as a basis for all
  9 * the Linear ADT's that will be developed in the CMPP 307 class at SAIT. The
 10 * implementors of this interface will be required to add all the functionality,
 11 * there will be no <code>UnsupportedOperationExceptions</code> allowed.
 12 * </p>
 13 * Created on: 1-Jun-2004
 14 * 
 15 * @author Don Heninger
 16 * @version 1.0
 17 */

 18public interface List extends Serializable
 19{
 20    /**
 21     * The size method will return the current element count contained in the
 22     * list. If the list contains more the Integer.MAX_VALUE, then
 23     * Integer.MAX_VALUE is return.
 24     * 
 25     * @return current element count.
 26     */

 27    public int size();
 28    
 29    /**
 30     * Removes all of the elements from this list. This list will be empty after
 31     * this call returns (unless it throws an exception).
 32     */

 33    public void clear();
 34    
 35    /**
 36     * Inserts the specified element at the specified position in this list.
 37     * Shifts the element currently at that position (if any) and any subsequent
 38     * elements to the right (adds one to their indices).
 39     * 
 40     * @param index index at which the specified element is to be inserted.
 41     * @param toAdd element to be inserted.
 42     * @throws ClassCastException if the class of the specified element prevents
 43     *             it from being added to this list.
 44     * @throws IllegalArgumentException if some aspect of the specified element
 45     *             prevents it from being added to this list.
 46     * @throws NullPointerException if the specified element is null and this
 47     *             list does not support null elements.
 48     * @throws IndexOutOfBoundsException if the index is out of range (index < 0 ||
 49     *             index > size()).
 50     */

 51    public void add(int index, Object toAdd) throws ClassCastException,
 52            IllegalArgumentException, NullPointerException,
 53            IndexOutOfBoundsException;
 54    
 55    /**
 56     * <p>
 57     * Appends the specified element to the end of this list.
 58     * </p>
 59     * Lists that support this operation may place limitations on what elements
 60     * may be added to this list. In particular, some lists will refuse to add
 61     * null elements, and others will impose restrictions on the type of
 62     * elements that may be added. List classes should clearly specify in their
 63     * documentation any restrictions on what elements may be added.
 64     * 
 65     * @param toAdd element to be appended to this list.
 66     * @return true if successful.
 67     * @throws ClassCastException if the class of the specified element prevents
 68     *             it from being added to this list.
 69     * @throws IllegalArgumentException if some aspect of the specified element
 70     *             prevents it from being added to this list.
 71     * @throws NullPointerException if the specified element is null and this
 72     *             list does not support null elements.
 73     * @throws IndexOutOfBoundsException if the index is out of range (index < 0 ||
 74     *             index > size()).
 75     */

 76    public boolean add(Object toAdd) throws ClassCastException,
 77            IllegalArgumentException, NullPointerException,
 78            IndexOutOfBoundsException;
 79    
 80    /**
 81     * Appends all of the elements in the specified collection to the end of
 82     * this list, in the order that they are returned by the specified
 83     * collection's iterator. The behavior of this operation is unspecified if
 84     * the specified collection is modified while the operation is in progress.
 85     * (Note that this will occur if the specified collection is this list, and
 86     * it's nonempty.)
 87     * 
 88     * @param toAdd the new sub list to be added.
 89     * @return true if the operation is successful.
 90     * @throws ClassCastException if the class of the specified element prevents
 91     *             it from being added to this list.
 92     * @throws IllegalArugmentException if some aspect of the specified element
 93     *             prevents it from being added to this list.
 94     * @throws NullPointerException if the specified element is null and this
 95     *             list does not support null elements.
 96     */

 97    public boolean addAll(List toAdd) throws ClassCastException,
 98            IllegalArgumentException, NullPointerException;
 99    
100    /**
101     * Returns the element at the specified position in this list.
102     * 
103     * @param index index of element to return.
104     * @return the element at the specified position in this list.
105     * @throws IndexOutOfBoundsException if the index is out of range (index < 0 ||
106     *             index > size()).
107     */

108    public Object get(int index) throws IndexOutOfBoundsException;
109    
110    /**
111     * Removes the element at the specified position in this list. Shifts any
112     * subsequent elements to the left (subtracts one from their indices).
113     * Returns the element that was removed from the list.
114     * 
115     * @param index index of element to remove.
116     * @return the removed element.
117     * @throws IndexOutOfBoundsException if the index is out of range (index < 0 ||
118     *             index > size()).
119     */

120    public Object remove(int index) throws IndexOutOfBoundsException;
121    
122    /**
123     * Removes the first occurrence in this list of the specified element. If
124     * this list does not contain the element, it is unchanged. More formally,
125     * removes the element with the lowest index i such that (o==null ?
126     * get(i)==null : o.equals(get(i))) (if such an element exists).
127     * 
128     * @param toRemove element to be removed from this list, if present.
129     * @return if this list contained the specified element.
130     * @throws ClassCastException if the class of the specified element prevents
131     *             it from being added to this list.
132     * @throws NullPointerException if the specified element is null and this
133     *             list does not support null elements.
134     */

135    public boolean remove(Object toRemove) throws ClassCastException,
136            NullPointerException;
137    
138    /**
139     * Replaces the element at the specified position in this list with the
140     * specified element (optional operation).
141     * 
142     * @param index index of element to replace.
143     * @param toChange element to be stored at the specified position.
144     * @return the element previously at the specified position.
145     * @throws ClassCastException if the class of the specified element prevents
146     *             it from being added to this list.
147     * @throws IllegalArugmentException if some aspect of the specified element
148     *             prevents it from being added to this list.
149     * @throws NullPointerException if the specified element is null and this
150     *             list does not support null elements.
151     * @throws IndexOutOfBoundsException if the index is out of range (index < 0 ||
152     *             index > size()).
153     */

154    public Object set(int index, Object toChange) throws ClassCastException,
155            IllegalArgumentException, NullPointerException,
156            IndexOutOfBoundsException;
157    
158    /**
159     * Returns <code>true</code> if this list contains no elements.
160     * 
161     * @return <code>true</code> if this list contains no elements.
162     */

163    public boolean isEmpty();
164    
165    /**
166     * Returns true if this list contains the specified element. More formally,
167     * returns true if and only if this list contains at least one element e
168     * such that (o==null ? e==null : o.equals(e)).
169     * 
170     * @param toFind element whose presence in this list is to be tested.
171     * @return true if this list contains the specified element.
172     * @throws ClassCastException if the class of the specified element prevents
173     *             it from being added to this list.
174     * @throws NullPointerException if the specified element is null and this
175     *             list does not support null elements.
176     */

177    public boolean contains(Object toFind) throws ClassCastException,
178            NullPointerException;
179    
180    /**
181     * Returns an array containing all of the elements in this list in proper
182     * sequence; the runtime type of the returned array is that of the specified
183     * array. Obeys the general contract of the Collection.toArray(Object[])
184     * method.
185     * 
186     * @param toHold the array into which the elements of this list are to be
187     *            stored, if it is big enough; otherwise, a new array of the
188     *            same runtime type is allocated for this purpose.
189     * @return an array containing the elements of this list.
190     * @throws ArrayStoreException if the runtime type of the specified array is
191     *             not a supertype of the runtime type of every element in this
192     *             list.
193     * @throws NullPointerException if the specified array is null.
194     */

195    public Object[] toArray(Object[] toHold) throws ArrayStoreException,
196            NullPointerException;
197    
198    /**
199     * Returns an array containing all of the elements in this list in proper
200     * sequence. Obeys the general contract of the Collection.toArray method.
201     * 
202     * @return an array containing all of the elements in this list in proper
203     *         sequence.
204     */

205    public Object[] toArray();
206    
207    /**
208     * Returns an iterator over the elements in this list in proper sequence.
209     * 
210     * @return an iterator over the elements in this list in proper sequence.
211     */

212    @SuppressWarnings("unchecked")
213    public Iterator iterator();
214}

215
  1package list;
  2
  3import java.io.Serializable;
  4import java.util.*;
  5
  6/**
  7 * This is the doubly linked list class which implements List interface
  8 * @author 
  9 * @version 1.0
 10 */

 11public class DoublyLinkedList implements List
 12{
 13    /**
 14     * Attributes
 15     */

 16    private static final long serialVersionUID = 1L;
 17    private Node head;
 18    private Node tail;
 19    private int size;
 20    
 21    /**
 22     * Constructor
 23     */

 24    public DoublyLinkedList()
 25    {
 26        this.head = null;
 27        this.tail = null;
 28        this.size = 0;
 29    }

 30    
 31    /*
 32     * (non-Javadoc)
 33     * 
 34     * @see list.List#size()
 35     */

 36    public int size()
 37    {
 38        return this.size;
 39    }

 40    
 41    /*
 42     * (non-Javadoc)
 43     * 
 44     * @see list.List#clear()
 45     */

 46    public void clear()
 47    {
 48        this.head = null;
 49        this.tail = null;
 50        this.size = 0;
 51    }

 52    
 53    /*
 54     * (non-Javadoc)
 55     * 
 56     * @see list.List#add(int, java.lang.Object)
 57     */

 58    public void add(int index, Object toAdd) throws ClassCastException,
 59            IllegalArgumentException, NullPointerException,
 60            IndexOutOfBoundsException
 61    {
 62        if(this.size == Integer.MAX_VALUE)
 63        {
 64            throw new IndexOutOfBoundsException();
 65        }

 66        if((index < 0 || index > this.size - 1&& this.size != 0)
 67        {
 68            throw new IndexOutOfBoundsException();
 69        }

 70        if(this.size == 0)
 71        {
 72            this.head = new Node(toAdd);
 73            this.tail = new Node(toAdd);
 74            this.size++;
 75        }

 76        else if(this.size == 1)
 77        {
 78            Node added = new Node(toAdd);
 79            added.setNext(this.tail);
 80            this.tail.setPrevious(added);
 81            this.head = added;
 82            this.size++;
 83        }

 84        else
 85        {
 86            Node added = new Node(toAdd);
 87            if(index == 0)
 88            {
 89                added.setNext(this.head);
 90                this.head.setPrevious(added);
 91                this.head = added;
 92                this.size++;
 93            }

 94            else
 95            {
 96                Node previous = getNode(index - 1);
 97                Node next = getNode(index);
 98                added.setPrevious(previous);
 99                added.setNext(next);
100                previous.setNext(added);
101                next.setPrevious(added);
102                this.size++;
103            }

104        }

105    }

106    
107    /**
108     * Method that will get the Node at a given position
109     * 
110     * @param position
111     * @return
112     * @throws IndexOutOfBoundsException
113     */

114    private Node getNode(int index) throws IndexOutOfBoundsException
115    {
116        if((index < 0 || index > this.size - 1&& this.size != 0)
117        {
118            throw new IndexOutOfBoundsException();
119        }

120        if(this.size == 0)
121        {
122            return null;
123        }

124        Node current;
125        if(index - 0 < this.size - index)
126        {
127            current = this.head;
128            for(int i = 0; i < index; i++)
129            {
130                current = current.getNext();
131            }

132        }

133        else
134        {
135            current = this.tail;
136            for(int i = this.size - 1; i > index; i--)
137            {
138                current = current.getPrevious();
139            }

140        }

141        return current;
142    }

143    
144    /*
145     * (non-Javadoc)
146     * 
147     * @see list.List#add(java.lang.Object)
148     */

149    public boolean add(Object toAdd) throws ClassCastException,
150            IllegalArgumentException, NullPointerException,
151            IndexOutOfBoundsException
152    {
153        if(this.size == Integer.MAX_VALUE)
154        {
155            throw new IndexOutOfBoundsException();
156        }

157        if(this.size == 0)
158        {
159            this.head = new Node(toAdd);
160            this.tail = new Node(toAdd);
161            this.size++;
162        }

163        else if(this.size == 1)
164        {
165            Node added = new Node(toAdd);
166            added.setPrevious(this.head);
167            this.head.setNext(added);
168            this.tail = added;
169            this.size++;
170        }

171        else
172        {
173            Node appended = new Node(toAdd);
174            appended.setPrevious(this.tail);
175            this.tail.setNext(appended);
176            this.tail = appended;
177            this.size++;
178        }

179        return true;
180    }

181    
182    /*
183     * (non-Javadoc)
184     * 
185     * @see list.List#addAll(list.List)
186     */

187    @SuppressWarnings("unchecked")
188    public boolean addAll(List toAdd) throws ClassCastException,
189            IllegalArgumentException, NullPointerException
190    {
191        if(this.size + toAdd.size() > Integer.MAX_VALUE)
192        {
193            throw new IndexOutOfBoundsException();
194        }

195        if(toAdd == this)
196        {
197            List temp = new DoublyLinkedList();
198            Iterator iterator = toAdd.iterator();
199            while(iterator.hasNext())
200            {
201                temp.add(iterator.next());
202            }

203            iterator = temp.iterator();
204            while(iterator.hasNext())
205            {
206                this.add(iterator.next());
207            }

208        }

209        else
210        {
211            Iterator iterator = toAdd.iterator();
212            while(iterator.hasNext())
213            {
214                this.add(iterator.next());
215            }

216        }

217        return true;
218    }

219    
220    /*
221     * (non-Javadoc)
222     * 
223     * @see list.List#get(int)
224     */

225    public Object get(int index) throws IndexOutOfBoundsException
226    {
227        if((index < 0 || index > this.size - 1&& this.size != 0)
228        {
229            throw new IndexOutOfBoundsException();
230        }

231        if(this.size == 0)
232        {
233            return null;
234        }

235        return getNode(index).getElement();
236    }

237    
238    /*
239     * (non-Javadoc)
240     * 
241     * @see list.List#remove(int)
242     */

243    public Object remove(int index) throws IndexOutOfBoundsException
244    {
245        if((index < 0 || index > this.size - 1&& this.size != 0)
246        {
247            throw new IndexOutOfBoundsException();
248        }

249        if(this.size == 0)
250        {
251            return null;
252        }

253        else if(this.size == 1)
254        {
255            Object object = this.head.getElement();
256            this.head = null;
257            this.tail = null;
258            this.size--;
259            return object;
260        }

261        else if(this.size == 2)
262        {
263            if(index == 0)
264            {
265                Object object = this.head.getElement();
266                this.tail.setPrevious(null);
267                this.head.setNext(null);
268                this.head.setElement(this.tail.getElement());
269                this.size--;
270                return object;
271            }

272            else
273            {
274                Object object = this.tail.getElement();
275                this.head.setNext(null);
276                this.tail.setPrevious(null);
277                this.tail.setElement(this.head.getElement());
278                this.size--;
279                return object;
280            }

281        }

282        else
283        {
284            if(index == this.size - 1)
285            {
286                Object object = this.tail.getElement();
287                this.tail = this.tail.getPrevious();
288                this.tail.setNext(null);
289                this.size--;
290                return object;
291            }

292            else if(index == 0)
293            {
294                Object object = this.head.getElement();
295                this.head = this.head.getNext();
296                this.head.setPrevious(null);
297                this.size--;
298                return object;
299            }

300            else
301            {
302                Node current = getNode(index);
303                Node previous = current.getPrevious();
304                Node next = current.getNext();
305                previous.setNext(next);
306                next.setPrevious(previous);
307                this.size--;
308                return current.getElement();
309            }

310        }

311    }

312    
313    /*
314     * (non-Javadoc)
315     * 
316     * @see list.List#remove(java.lang.Object)
317     */

318    public boolean remove(Object toRemove) throws ClassCastException,
319            NullPointerException
320    {
321        if(toRemove == null)
322        {
323            throw new NullPointerException();
324        }

325        int index = indexOf(toRemove);
326        try
327        {
328            remove(index);
329        }

330        catch(Exception e)
331        {
332        }

333        return true;
334    }

335    
336    /**
337     * Method that will return the index of the object in the list
338     * 
339     * @param object
340     * @return
341     */

342    private int indexOf(Object object)
343    {
344        if(this.size == 0)
345        {
346            return -1;
347        }

348        else
349        {
350            Node current = this.head;
351            int i = 0;
352            do
353            {
354                if(current.getElement().equals(object))
355                {
356                    return i;
357                }

358                else
359                {
360                    current = current.getNext();
361                    i++;
362                }

363            }

364            while(current != null);
365            return i;
366        }

367    }

368    
369    /*
370     * (non-Javadoc)
371     * 
372     * @see list.List#set(int, java.lang.Object)
373     */

374    public Object set(int index, Object toChange) throws ClassCastException,
375            IllegalArgumentException, NullPointerException,
376            IndexOutOfBoundsException
377    {
378        Node node = getNode(index);// will throw exception when index out of
379        // bounds
380        Object object = node.getElement();
381        node.setElement(toChange);
382        return object;
383    }

384    
385    /*
386     * (non-Javadoc)
387     * 
388     * @see list.List#isEmpty()
389     */

390    public boolean isEmpty()
391    {
392        if(this.size == 0)
393        {
394            return true;
395        }

396        else
397        {
398            return false;
399        }

400    }

401    
402    /*
403     * (non-Javadoc)
404     * 
405     * @see list.List#contains(java.lang.Object)
406     */

407    public boolean contains(Object toFind) throws ClassCastException,
408            NullPointerException
409    {
410        Node current = this.head;
411        do
412        {
413            if(current.getElement().equals(toFind))
414            {
415                return true;
416            }

417            else
418            {
419                current = current.getNext();
420            }

421        }

422        while(current != null);
423        return false;
424    }

425    
426    /*
427     * (non-Javadoc)
428     * 
429     * @see list.List#toArray(java.lang.Object[])
430     */

431    @SuppressWarnings("unchecked")
432    public Object[] toArray(Object[] toHold) throws ArrayStoreException,
433            NullPointerException
434    {
435        if(toHold.length >= this.size)
436        {
437            int pointer = 0;
438            Iterator iterator = this.iterator();
439            while(iterator.hasNext())
440            {
441                toHold[pointer] = iterator.next();
442                pointer++;
443            }

444            return toHold;
445        }

446        else
447        {
448            Object[] objects = new Object[this.size];
449            int pointer = 0;
450            Iterator iterator = this.iterator();
451            while(iterator.hasNext())
452            {
453                objects[pointer] = iterator.next();
454                pointer++;
455            }

456            return objects;
457        }

458    }

459    
460    /*
461     * (non-Javadoc)
462     * 
463     * @see list.List#toArray()
464     */

465    @SuppressWarnings("unchecked")
466    public Object[] toArray()
467    {
468        Object[] objects = new Object[this.size];
469        int pointer = 0;
470        Iterator iterator = this.iterator();
471        while(iterator.hasNext())
472        {
473            objects[pointer] = iterator.next();
474            pointer++;
475        }

476        return objects;
477    }

478    
479    /*
480     * (non-Javadoc)
481     * 
482     * @see list.List#iterator()
483     */

484    @SuppressWarnings("unchecked")
485    public Iterator iterator()
486    {
487        JoeyIterator ji = new JoeyIterator(thisthis.head);
488        return ji;
489    }

490    @SuppressWarnings("unchecked")
491    private class JoeyIterator implements Iterator
492    {
493        /**
494         * Attributes
495         */

496        private DoublyLinkedList dll;
497        private Node node;
498        private boolean started;
499        
500        /**
501         * Constructor
502         */

503        public JoeyIterator(DoublyLinkedList dll, Node node)
504        {
505            this.dll = dll;
506            this.node = node;
507            this.started = false;
508        }

509        
510        /*
511         * (non-Javadoc)
512         * 
513         * @see java.util.Iterator#hasNext()
514         */

515        @Override
516        public boolean hasNext()
517        {
518            if(this.started == false)
519            {
520                if(node != null)
521                {
522                    return true;
523                }

524                else
525                {
526                    return false;
527                }

528            }

529            Node temp = node.getNext();
530            if(temp != null)
531            {
532                return true;
533            }

534            else
535            {
536                return false;
537            }

538        }

539        
540        /*
541         * (non-Javadoc)
542         * 
543         * @see java.util.Iterator#next()
544         */

545        @Override
546        public Object next()
547        {
548            if(this.started == false)
549            {
550                this.started = true;
551                if(node != null)
552                {
553                    return node.getElement();
554                }

555                else
556                {
557                    return null;
558                }

559            }

560            else
561            {
562                node = node.getNext();
563                return node.getElement();
564            }

565        }

566        
567        /*
568         * (non-Javadoc)
569         * 
570         * @see java.util.Iterator#remove()
571         */

572        @Override
573        public void remove()
574        {
575            try
576            {
577                dll.remove(dll.size() - 1);
578            }

579            catch(Exception e)
580            {
581            }

582        }

583    }

584    /**
585     * @author 
586     * @version 1.0
587     */

588    public class Node implements Serializable
589    {
590        /**
591         * Attributes
592         */

593        private static final long serialVersionUID = 1L;
594        private Object element;
595        private Node previous;
596        private Node next;
597        
598        /**
599         * Constructor
600         * 
601         * @param element the element to set
602         */

603        public Node(Object element)
604        {
605            this.element = element;
606            this.previous = null;
607            this.next = null;
608        }

609        
610        /**
611         * @return the element
612         */

613        public Object getElement()
614        {
615            return element;
616        }

617        
618        /**
619         * @param element the element to set
620         */

621        public void setElement(Object element)
622        {
623            this.element = element;
624        }

625        
626        /**
627         * @return the next
628         */

629        public Node getNext()
630        {
631            return next;
632        }

633        
634        /**
635         * @param next the next to set
636         */

637        public void setNext(Node next)
638        {
639            this.next = next;
640        }

641        
642        /**
643         * @return the previous
644         */

645        public Node getPrevious()
646        {
647            return previous;
648        }

649        
650        /**
651         * @param previous the previous to set
652         */

653        public void setPrevious(Node previous)
654        {
655            this.previous = previous;
656        }

657    }

658}

659
posted @ 2007-12-03 06:35  N/A2011  阅读(493)  评论(0编辑  收藏  举报