算法Sedgewick第四版-第1章基础-016一list

 

  1 import java.util.Iterator;
  2 import java.util.NoSuchElementException;
  3 
  4 public class List<Item> implements Iterable<Item>
  5 {
  6     private int N;
  7     private Node first;
  8     private Node last;
  9 
 10     private class Node
 11     {
 12         private Item item;
 13         private Node next;
 14     }
 15 
 16     public List()
 17     {
 18         first = null;
 19         last  = null;
 20     }
 21     
 22     public List(Item[] a)
 23     {
 24         for (Item t : a)
 25             append(t);
 26     }
 27 
 28     public List(Iterable<Item> coll)
 29     {
 30         for (Item t : coll)
 31             append(t);
 32     }
 33 
 34     public boolean isEmpty()
 35     {
 36         return first == null;
 37     }
 38 
 39     public int size()
 40     {
 41         return N;     
 42     }
 43     
 44     public Item first()
 45     {
 46         if (isEmpty()) throw new RuntimeException("List is empty");
 47         return first.item;
 48     }
 49     
 50     public Item last()
 51     {
 52         if (isEmpty()) throw new RuntimeException("List is empty");
 53         return last.item;
 54     }
 55     
 56     public Item removeFirst()
 57     {
 58         if (isEmpty()) throw new RuntimeException("List is empty");
 59         Item item = first.item;
 60         first = first.next;
 61         N--;
 62         if (isEmpty()) last = null;   // to avoid loitering
 63         return item;
 64     }
 65     
 66     public void prepend(Item item)
 67     {
 68         Node x = new Node();
 69         x.item = item;
 70         if (isEmpty()) { first = x;      last = x;  }
 71         else           { x.next = first; first = x; }
 72         N++;
 73     }
 74 
 75     public void append(Item item)
 76     {
 77         Node x = new Node();
 78         x.item = item;
 79         if (isEmpty()) { first = x;     last = x; }
 80         else           { last.next = x; last = x; }
 81         N++;
 82     }
 83     
 84     public String toString()
 85     {
 86         StringBuilder s = new StringBuilder();
 87         for (Item item : this)
 88             s.append(item + " ");
 89         return s.toString();
 90     } 
 91  
 92     public Iterator<Item> iterator()
 93     {
 94         return new ListIterator();  
 95     }
 96 
 97     private class ListIterator implements Iterator<Item>
 98     {
 99         private Node current = first;
100 
101         public boolean hasNext()  { return current != null;                     }
102         public void remove()      { throw new UnsupportedOperationException();  }
103 
104         public Item next()
105         {
106             if (!hasNext()) throw new NoSuchElementException();
107             Item item = current.item;
108             current = current.next; 
109             return item;
110         }
111     }
112     
113     /*****************
114      * Exercise 1.3.19
115      *****************/
116     public Item removeLast()
117     {
118         if (isEmpty()) throw new RuntimeException("List is empty");
119         if (first == last) return removeFirst();
120         Item item = last.item;
121         
122         Node prev = null,
123              curr = first;
124         while (curr.next != null)
125         {
126             prev = curr;
127             curr = curr.next;
128         }
129         prev.next = null;
130         last = prev;
131         N--;
132         
133         return item;
134     }
135     
136     /*****************
137      * Exercise 1.3.20
138      *****************/
139     public Item delete(int k)
140     {
141         if (k < 1) return null;
142         
143         int i = 1;
144         Node prev = null,
145              curr = first;
146         
147         while (i < k && curr != null)
148         {
149             prev = curr;
150             curr = curr.next;
151             i++;
152         }
153         
154         if (curr != null)
155         {
156             if (prev == null)
157                 first = curr.next;
158             else
159                 prev.next = curr.next;
160             
161             if (curr.next == null)
162                 last = prev;
163             
164             N--;
165             return curr.item;
166         }
167         else
168             return null;
169     }
170     
171     /*************************************
172      * Exercise 1.3.21
173      * (Renamed from find() to contains())
174      *************************************/
175     public boolean contains(Item item)
176     {
177         Node curr = first;
178         while (curr != null && !curr.item.equals(item))
179             curr = curr.next;
180         return curr != null;
181     }
182     
183     /*****************
184      * Exercise 1.3.26
185      *****************/
186     public void remove(Item item)
187     {
188         List<Integer> idx = new List<Integer>();
189         int i = 1;
190         
191         for (Item x : this)
192         {
193             if (x.equals(item))
194                 idx.prepend(i);
195             i++;
196         }
197         
198         for (int k : idx)
199             delete(k);
200     }
201     
202     /***************************************
203      * Recursive solution to Exercise 1.3.26
204      ***************************************/
205     public void removeRec(Item item)
206     {
207         first = remove_Node(first, item);
208         setLastAndN();
209     }
210     
211     private Node remove_Node(Node node, Item item)
212     {
213         if (node != null)
214         {
215             Node rest = remove_Node(node.next, item);
216             
217             if (node.item.equals(item))
218                 return rest;
219             else
220             {
221                 node.next = rest;
222                 return node;
223             }
224         }
225         else
226             return null;
227     }
228     
229     private void setLastAndN()
230     {
231         last = first;
232         N = 0;
233         if (first != null)
234         {
235             N++;
236             while (last.next != null)
237             {
238                 last = last.next;
239                 N++;
240             }
241         }
242     }
243     
244     
245     /*********************
246      * Operations on nodes
247      *********************/
248     
249     public Node node(int k)
250     {
251         if (k < 1) return null;
252         
253         int i = 1;
254         Node curr = first;
255         
256         while (i < k && curr != null)
257         {
258             curr = curr.next;
259             i++;
260         }
261         
262         return curr;
263     }
264     
265     public Node createNode(Item item)
266     {
267         Node node = new Node();
268         node.item = item;
269         return node;
270     }
271     
272     /*****************
273      * Exercise 1.3.24
274      *****************/
275     public void removeAfter(Node node)
276     {
277         if (node != null && node.next != null)
278         {
279             if (node.next.next == null)
280                 last = node;
281             node.next = node.next.next;
282             N--;
283         }
284     }
285     
286     /*****************
287      * Exercise 1.3.25
288      *****************/
289     public void insertAfter(Node a, Node b)
290     {
291         if (a != null && b != null)
292         {
293             if (last == a)
294                 last = b;
295             b.next = a.next;
296             a.next = b;
297             N++;
298         }
299     }
300     
301     /*************************************************
302      * Exercise 1.3.27
303      * Type 'Item' must implement interface Comparable
304      *************************************************/
305     public Item max(Node node)
306     {
307         if (node == null) throw new RuntimeException("List is empty");
308         return max(node, null);
309     }
310     
311     public Item max(Node node, Item def)
312     {
313         if (node == null)
314             return def;
315         
316         Item max = node.item;
317         Node curr = node;
318         
319         while (curr.next != null)
320         {
321             curr = curr.next;
322             if (((Comparable)max).compareTo(curr.item) < 0)
323                 max = curr.item;
324         }
325         
326         return max;
327     }
328     
329     /*************************************************
330      * Exercise 1.3.28
331      * (recursive variant of Exercise 1.3.27)
332      * Type 'Item' must implement interface Comparable
333      *************************************************/
334     public Item maxRec(Node node, Item def)
335     {
336         if (node == null)
337             return def;
338         else
339             return maxRec(node);
340     }
341     
342     public Item maxRec(Node node)
343     {
344         if (node == null) throw new RuntimeException("List is empty");
345         
346         if (node.next == null)
347             return node.item;
348         else
349         {
350             Item maxTail = maxRec(node.next);
351             return ((Comparable)node.item).compareTo(maxTail) > 0 ? node.item : maxTail;
352         }
353     }
354     
355     /*****************
356      * Exercise 1.3.30
357      *****************/
358     public void reverse()
359     {
360         first = reverse(first);
361         setLastAndN();
362     }
363     
364     public Node reverse(Node node)
365     {
366         Node srcFirst = node,
367              destFirst = null;
368         while (srcFirst != null)
369         {
370             Node next = srcFirst.next;
371             srcFirst.next = destFirst;
372             destFirst = srcFirst;
373             srcFirst = next;
374         }
375         
376         return destFirst;
377     }
378     
379     /***************************************
380      * Recursive solution to Exercise 1.3.30
381      ***************************************/
382     public void reverseRec()
383     {
384         first = reverseRec(first);
385         setLastAndN();
386     }
387     
388     private Node reverseRec(Node node)
389     {
390         return reverseRec(node, null);
391     }
392     
393     private Node reverseRec(Node srcFirst, Node destFirst)
394     {
395         if (srcFirst == null)
396             return destFirst;
397         else
398         {
399             Node next = srcFirst.next;
400             srcFirst.next = destFirst;
401             return reverseRec(next, srcFirst);
402         }
403     }
404         
405     
406     /************
407      * Unit tests
408      ************/
409     
410     private static void testBaseMethods()
411     {
412         int[] a = { 2, 4, 6, 8, 10, 12 };
413         
414         List<Integer> lst = new List<Integer>();
415         for (int i = 0; i < a.length; i++)
416             lst.append(a[i]);
417         showList(lst);
418         
419         lst = new List<Integer>();
420         for (int i = 0; i < a.length; i++)
421             lst.prepend(a[i]);
422         showList(lst);
423         
424         StdOut.println("removeFirst: " + lst.removeFirst());
425         showList(lst);
426     }
427     
428     private static void testRemoveLast()
429     {
430         List<Integer> lst = new List<Integer>(new Integer[] { 6, 8, 10, 12 });
431         showList(lst);
432         
433         while (!lst.isEmpty())
434         {
435             StdOut.println("removeLast: " + lst.removeLast());
436             showList(lst);
437         }
438     }
439     
440     private static void testDelete()
441     {
442         List<Integer> lst = new List<Integer>(new Integer[] { 2, 4, 6, 8, 10, 12 });
443         showList(lst);
444         
445         StdOut.printf("delete(%d): %s\n", 5, lst.delete(5));
446         showList(lst);
447         
448         StdOut.printf("delete(%d): %s\n", 1, lst.delete(1));
449         showList(lst);
450         
451         StdOut.printf("delete(%d): %s\n", 4, lst.delete(4));
452         showList(lst);
453         
454         StdOut.printf("delete(%d): %s\n", 8, lst.delete(8));
455         showList(lst);
456         
457         StdOut.printf("delete(%d): %s\n", 0, lst.delete(0));
458         showList(lst);
459         
460         while (!lst.isEmpty())
461         {
462             StdOut.printf("delete(%d): %s\n", 1, lst.delete(1));
463             showList(lst);
464         }
465     }
466     
467     private static void testContains()
468     {
469         Integer[] a = { 4, 6, 10, 12 };
470         List<Integer> lst = new List<Integer>(a);
471         showList(lst);
472         
473         StdOut.printf("contains(%d): %s\n", 0, lst.contains(0));
474         
475         for (int i = 0; i < a.length; i++)
476             StdOut.printf("contains(%d): %s\n", a[i], lst.contains(a[i]));
477     }
478     
479     private static void testRemove()
480     {
481         for (int k = 0; k < 8; k++)
482         {
483             List<Integer> lst1 = randomList(20, 0, 5);
484             List<Integer> lst2 = new List<Integer>(lst1);
485             StdOut.println(lst1);
486             StdOut.println();
487             
488             int n = StdRandom.uniform(0, 5);
489             
490             StdOut.printf("remove(%d):\n", n);
491             lst1.remove(n);
492             showList(lst1);
493             
494             StdOut.printf("removeRec(%d):\n", n);
495             lst2.removeRec(n);
496             showList(lst2);
497             StdOut.println();
498         }
499     }
500     
501     private static void testReverse()
502     {
503         int n = 10;
504         Integer[] a = new Integer[n];
505         for (int i = 0; i < n; i++)
506             a[i] = 2 * (i + 1);
507         
508         testReverse(new List<Integer>(a));
509         StdOut.println();
510         
511         testReverse(randomList(20, 0, 10));
512         StdOut.println();
513         
514         testReverse(new List<Integer>(new Integer[] { 37 }));
515         StdOut.println();
516         
517         testReverse(new List<Integer>(new Integer[] { }));
518         StdOut.println();
519     }
520     
521     private static void testReverse(List<Integer> lst)
522     {
523         List<Integer> lst1 = lst;
524         List<Integer> lst2 = new List<Integer>(lst1);
525         StdOut.println(lst1);
526         
527         StdOut.println("reverse():");
528         lst1.reverse();
529         StdOut.println(lst1);
530         
531         StdOut.println("reverseRec():");
532         lst2.reverseRec();
533         StdOut.println(lst2);
534     }
535     
536     private static void testNode()
537     {
538         List<Integer> lst = new List<Integer>(new Integer[] { 2, 6, 12 });
539         showList(lst);
540         
541         for (int i = -1; i <= 4; i++)
542             StdOut.printf("node(%d): %s\n", i, lst.node(i) != null ? lst.node(i).item : null);
543     }
544     
545     private static void testRemoveAfter()
546     {
547         List<Integer> lst = new List<Integer>(new Integer[] { 2, 6, 8, 10, 12 });
548         showList(lst);
549         
550         int[] k = { 0, 2, 1, 5, 3, 2, 1 };
551         
552         for (int i = 0; i < k.length; i++)
553         {
554             StdOut.printf("removeAfter(node(%d)):\n", k[i]);
555             lst.removeAfter(lst.node(k[i]));
556             showList(lst);
557         }
558     }
559     
560     private static void testInsertAfter()
561     {
562         List<Integer> lst = new List<Integer>(new Integer[] { 2, 6, 10, 12 });
563         showList(lst);
564         
565         StdOut.printf("insertAfter(node(%d), null):\n", 1);
566         lst.insertAfter(lst.node(1), null);
567         showList(lst);
568         
569         int ia = 1,
570             b = 3;
571         StdOut.printf("insertAfter(node(%d), createNode(%d)):\n", ia, b);
572         lst.insertAfter(lst.node(ia), lst.createNode(b));
573         showList(lst);
574         
575         ia = 5;
576         b = 25;
577         StdOut.printf("insertAfter(node(%d), createNode(%d)):\n", ia, b);
578         lst.insertAfter(lst.node(ia), lst.createNode(b));
579         showList(lst);
580     }
581     
582     private static void testMax()
583     {
584         for (int k = 0; k < 8; k++)
585         {
586             List<Integer> lst = randomList(10, 100, 1000);
587             StdOut.println(lst);
588             
589             StdOut.printf("max():    %d\n", lst.max(lst.node(1)));
590             StdOut.printf("maxRec(): %d\n\n", lst.maxRec(lst.node(1)));
591         }
592     }
593     
594     
595     /*******************
596      * Unit test helpers
597      *******************/
598     
599     public static void showList(List lst)
600     {
601         StdOut.println(lst);
602         if (!lst.isEmpty())
603             StdOut.printf("Size: %d, First: %s, Last: %s\n\n", lst.size(), lst.first(), lst.last());
604         else
605             StdOut.printf("Size: %d\n\n", lst.size());
606     }
607     
608     private static List<Integer> randomList(int n, int a, int b)
609     {
610         Integer[] r = new Integer[n];
611         for (int i = 0; i < n; i++)
612             r[i] = StdRandom.uniform(a, b);
613         return new List<Integer>(r);
614     }
615     
616     public static void main(String[] args)
617     {
618         testBaseMethods();
619         StdOut.println();
620         
621         testRemoveLast();
622         StdOut.println();
623         
624         testDelete();
625         StdOut.println();
626         
627         testContains();
628         StdOut.println();
629         
630         testNode();
631         StdOut.println();
632         
633         testRemoveAfter();
634         StdOut.println();
635         
636         testInsertAfter();
637         StdOut.println();
638         
639         testRemove();
640         StdOut.println();
641         
642         testMax();
643         StdOut.println();
644         
645         testReverse();
646         StdOut.println();
647     }
648 }

 

posted @ 2016-04-19 17:52  shamgod  阅读(198)  评论(0编辑  收藏  举报
haha