算法Sedgewick第四版-第1章基础-021一双向链表,在遍历时可修改、删除元素

 

  1 package algorithms.ADT;
  2 
  3 /******************************************************************************
  4  *  Compilation:  javac DoublyLinkedList.java
  5  *  Execution:    java DoublyLinkedList
  6  *  Dependencies: StdOut.java
  7  *
  8  *  A list implemented with a doubly linked list. The elements are stored
  9  *  (and iterated over) in the same order that they are inserted.
 10  * 
 11  *  % java DoublyLinkedList 10
 12  *  10 random integers between 0 and 99
 13  *  24 65 2 39 86 24 50 47 13 4 
 14  *
 15  *  add 1 to each element via next() and set()
 16  *  25 66 3 40 87 25 51 48 14 5 
 17  *
 18  *  multiply each element by 3 via previous() and set()
 19  *  75 198 9 120 261 75 153 144 42 15 
 20  *
 21  *  remove elements that are a multiple of 4 via next() and remove()
 22  *  75 198 9 261 75 153 42 15 
 23  *
 24  *  remove elements that are even via previous() and remove()
 25  *  75 9 261 75 153 15 
 26  *
 27  ******************************************************************************/
 28 
 29 import java.util.ListIterator;
 30 import java.util.NoSuchElementException;
 31 
 32 import algorithms.util.StdOut;
 33 import algorithms.util.StdRandom;
 34 
 35 public class DoublyLinkedList<Item> implements Iterable<Item> {
 36     private int N;        // number of elements on list
 37     private Node pre;     // sentinel before first item
 38     private Node post;    // sentinel after last item
 39 
 40     public DoublyLinkedList() {
 41         pre  = new Node();
 42         post = new Node();
 43         pre.next = post;
 44         post.prev = pre;
 45     }
 46 
 47     // linked list node helper data type
 48     private class Node {
 49         private Item item;
 50         private Node next;
 51         private Node prev;
 52     }
 53 
 54     public boolean isEmpty()    { return N == 0; }
 55     public int size()           { return N;      }
 56 
 57     // add the item to the list
 58     public void add(Item item) {
 59         Node last = post.prev;
 60         Node x = new Node();
 61         x.item = item;
 62         x.next = post;
 63         x.prev = last;
 64         post.prev = x;
 65         last.next = x;
 66         N++;
 67     }
 68 
 69     public ListIterator<Item> iterator()  { return new DoublyLinkedListIterator(); }
 70 
 71     // assumes no calls to DoublyLinkedList.add() during iteration
 72     private class DoublyLinkedListIterator implements ListIterator<Item> {
 73         private Node current      = pre.next;  // the node that is returned by next()
 74         private Node lastAccessed = null;      // the last node to be returned by prev() or next()
 75                                                // reset to null upon intervening remove() or add()
 76         private int index = 0;
 77 
 78         public boolean hasNext()      { return index < N; }
 79         public boolean hasPrevious()  { return index > 0; }
 80         public int previousIndex()    { return index - 1; }
 81         public int nextIndex()        { return index;     }
 82 
 83         public Item next() {
 84             if (!hasNext()) throw new NoSuchElementException();
 85             lastAccessed = current;
 86             Item item = current.item;
 87             current = current.next; 
 88             index++;
 89             return item;
 90         }
 91 
 92         public Item previous() {
 93             if (!hasPrevious()) throw new NoSuchElementException();
 94             current = current.prev;
 95             index--;
 96             lastAccessed = current;
 97             return current.item;
 98         }
 99 
100         // replace the item of the element that was last accessed by next() or previous()
101         // condition: no calls to remove() or add() after last call to next() or previous()
102         public void set(Item item) {
103             if (lastAccessed == null) throw new IllegalStateException();
104             lastAccessed.item = item;
105         }
106 
107         // remove the element that was last accessed by next() or previous()
108         // condition: no calls to remove() or add() after last call to next() or previous()
109         public void remove() { 
110             if (lastAccessed == null) throw new IllegalStateException();
111             Node x = lastAccessed.prev;
112             Node y = lastAccessed.next;
113             x.next = y;
114             y.prev = x;
115             N--;
116             if (current == lastAccessed)
117                 current = y;
118             else
119                 index--;
120             lastAccessed = null;
121         }
122 
123         // add element to list 
124         public void add(Item item) {
125             Node x = current.prev;
126             Node y = new Node();
127             Node z = current;
128             y.item = item;
129             x.next = y;
130             y.next = z;
131             z.prev = y;
132             y.prev = x;
133             N++;
134             index++;
135             lastAccessed = null;
136         }
137 
138     }
139 
140     public String toString() {
141         StringBuilder s = new StringBuilder();
142         for (Item item : this)
143             s.append(item + " ");
144         return s.toString();
145     }
146 
147     // a test client
148     public static void main(String[] args) {
149         int N  = Integer.parseInt(args[0]);
150 
151         // add elements 1, ..., N
152         StdOut.println(N + " random integers between 0 and 99");
153         DoublyLinkedList<Integer> list = new DoublyLinkedList<Integer>();
154         for (int i = 0; i < N; i++)
155             list.add(StdRandom.uniform(100));
156         StdOut.println(list);
157         StdOut.println();
158 
159         ListIterator<Integer> iterator = list.iterator();
160 
161         // go forwards with next() and set()
162         StdOut.println("add 1 to each element via next() and set()");
163         while (iterator.hasNext()) {
164             int x = iterator.next();
165             iterator.set(x + 1);
166         }
167         StdOut.println(list);
168         StdOut.println();
169 
170         // go backwards with previous() and set()
171         StdOut.println("multiply each element by 3 via previous() and set()");
172         while (iterator.hasPrevious()) {
173             int x = iterator.previous();
174             iterator.set(x + x + x);
175         }
176         StdOut.println(list);
177         StdOut.println();
178 
179 
180         // remove all elements that are multiples of 4 via next() and remove()
181         StdOut.println("remove elements that are a multiple of 4 via next() and remove()");
182         while (iterator.hasNext()) {
183             int x = iterator.next();
184             if (x % 4 == 0) iterator.remove();
185         }
186         StdOut.println(list);
187         StdOut.println();
188 
189 
190         // remove all even elements via previous() and remove()
191         StdOut.println("remove elements that are even via previous() and remove()");
192         while (iterator.hasPrevious()) {
193             int x = iterator.previous();
194             if (x % 2 == 0) iterator.remove();
195         }
196         StdOut.println(list);
197         StdOut.println();
198 
199 
200         // add elements via next() and add()
201         StdOut.println("add elements via next() and add()");
202         while (iterator.hasNext()) {
203             int x = iterator.next();
204             iterator.add(x + 1);
205         }
206         StdOut.println(list);
207         StdOut.println();
208 
209         // add elements via previous() and add()
210         StdOut.println("add elements via previous() and add()");
211         while (iterator.hasPrevious()) {
212             int x = iterator.previous();
213             iterator.add(x * 10);
214             iterator.previous();
215         }
216         StdOut.println(list);
217         StdOut.println();
218     }
219 }

 

posted @ 2016-04-20 11:21  shamgod  阅读(300)  评论(0编辑  收藏  举报
haha