算法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 }
时间: 2024-10-08 18:19:03

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

算法Sedgewick第四版-第1章基础-001递归

一. 方法可以调用自己(如果你对递归概念感到奇怪,请完成练习 1.1.16 到练习 1.1.22).例如,下面给出了 BinarySearch 的 rank() 方法的另一种实现.我们会经常使用递归,因为递归代码比相应的非递归代码更加简洁优雅.易懂.下面这种实现中的注释就言简意赅地说明了代码的作用.我们可以用数学归纳法证明这段注释所解释的算法的正确性.我们会在 3.1 节中展开这个话题并为二分查找提供一个这样的证明.编写递归代码时最重要的有以下三点.? 递归总有一个最简单的情况——方法的第一条语

算法Sedgewick第四版-第1章基础-008一用数组实现固定长度的栈

1 package algorithms.ADT; 2 3 /****************************************************************************** 4 * Compilation: javac FixedCapacityStackOfStrings.java 5 * Execution: java FixedCapacityStackOfStrings 6 * Dependencies: StdIn.java StdOut.

算法Sedgewick第四版-第1章基础-1.4 Analysis of Algorithms-005计测试算法

1. 1 package algorithms.analysis14; 2 3 import algorithms.util.StdOut; 4 import algorithms.util.StdRandom; 5 6 /****************************************************************************** 7 * Compilation: javac DoublingTest.java 8 * Execution: jav

算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-002插入排序法(Insertion sort)

一.介绍 1.时间和空间复杂度 运行过程 2.特点: (1)对于已排序或接近排好的数据,速度很快 (2)对于部分排好序的输入,速度快 二.代码 1 package algorithms.elementary21; 2 3 /****************************************************************************** 4 * Compilation: javac Insertion.java 5 * Execution: java I

算法Sedgewick第四版-第1章基础-018一解决不能声明泛型数组的两咱方法(强转或反射)

1. 1 /****************************************************************************** 2 * Compilation: javac ResizingArrayStackWithReflection.java 3 * Execution: java ResizingArrayStackWithReflection < input.txt 4 * Dependencies: StdIn.java StdOut.jav

算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-007归并排序(自下而上)

一. 1. 2. 3. 二.代码 1 package algorithms.mergesort22; 2 3 import algorithms.util.StdIn; 4 import algorithms.util.StdOut; 5 6 /****************************************************************************** 7 * Compilation: javac MergeBU.java 8 * Executio

算法Sedgewick第四版-第1章基础-1.3Bags, Queues, and Stacks-001可变在小的

1. package algorithms.stacks13; /****************************************************************************** * Compilation: javac ResizingArrayBag.java * Execution: java ResizingArrayBag * Dependencies: StdIn.java StdOut.java * * Bag implementatio

算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-006归并排序(Mergesort)

一. 1.特点 (1)merge-sort : to sort an array, divide it into two halves, sort the two halves (recursively), and then merge the results. As you will see, one of mergesort’s most attractive properties is that it guarantees to sort any array of N items in t

算法Sedgewick第四版-第1章基础-003一封装交易对象

1. 1 package ADT; 2 3 /****************************************************************************** 4 * Compilation: javac Transaction.java 5 * Execution: java Transaction 6 * Dependencies: StdOut.java 7 * 8 * Data type for commercial transactions.