comparison tango/tango/util/collection/impl/LLCell.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /*
2 File: LLCell.d
3
4 Originally written by Doug Lea and released into the public domain.
5 Thanks for the assistance and support of Sun Microsystems Labs, Agorics
6 Inc, Loral, and everyone contributing, testing, and using this code.
7
8 History:
9 Date Who What
10 24Sep95 dl@cs.oswego.edu Create from tango.util.collection.d working file
11
12 */
13
14
15 module tango.util.collection.impl.LLCell;
16
17 private import tango.util.collection.impl.Cell;
18
19 private import tango.util.collection.model.Comparator;
20
21 /**
22 *
23 *
24 * LLCells extend Cells with standard linkedlist next-fields,
25 * and provide a standard operations on them.
26 * <P>
27 * LLCells are pure implementation tools. They perform
28 * no argument checking, no result screening, and no synchronization.
29 * They rely on user-level classes (see for example LinkedList) to do such things.
30 * Still, the class is made `public' so that you can use them to
31 * build other kinds of collections or whatever, not just the ones
32 * currently supported.
33 *
34 author: Doug Lea
35 * @version 0.93
36 *
37 * <P> For an introduction to this package see <A HREF="index.html"> Overview </A>.
38 **/
39
40 public class LLCell(T) : Cell!(T)
41 {
42 alias Comparator!(T) ComparatorT;
43
44
45 protected LLCell next_;
46
47 /**
48 * Return the next cell (or null if none)
49 **/
50
51 public LLCell next()
52 {
53 return next_;
54 }
55
56 /**
57 * set to point to n as next cell
58 * @param n, the new next cell
59 **/
60
61 public void next(LLCell n)
62 {
63 next_ = n;
64 }
65
66 public this (T v, LLCell n)
67 {
68 super(v);
69 next_ = n;
70 }
71
72 public this (T v)
73 {
74 this(v, null);
75 }
76
77 public this ()
78 {
79 this(T.init, null);
80 }
81
82
83 /**
84 * Splice in p between current cell and whatever it was previously
85 * pointing to
86 * @param p, the cell to splice
87 **/
88
89 public final void linkNext(LLCell p)
90 {
91 if (p !is null)
92 p.next_ = next_;
93 next_ = p;
94 }
95
96 /**
97 * Cause current cell to skip over the current next() one,
98 * effectively removing the next element from the list
99 **/
100
101 public final void unlinkNext()
102 {
103 if (next_ !is null)
104 next_ = next_.next_;
105 }
106
107 /**
108 * Linear search down the list looking for element (using T.equals)
109 * @param element to look for
110 * Returns: the cell containing element, or null if no such
111 **/
112
113 public final LLCell find(T element)
114 {
115 for (LLCell p = this; p !is null; p = p.next_)
116 if (p.element() == element)
117 return p;
118 return null;
119 }
120
121 /**
122 * return the number of cells traversed to find first occurrence
123 * of a cell with element() element, or -1 if not present
124 **/
125
126 public final int index(T element)
127 {
128 int i = 0;
129 for (LLCell p = this; p !is null; p = p.next_)
130 {
131 if (p.element() == element)
132 return i;
133 else
134 ++i;
135 }
136 return -1;
137 }
138
139 /**
140 * Count the number of occurrences of element in list
141 **/
142
143 public final int count(T element)
144 {
145 int c = 0;
146 for (LLCell p = this; p !is null; p = p.next_)
147 if (p.element() == element)
148 ++c;
149 return c;
150 }
151
152 /**
153 * return the number of cells in the list
154 **/
155
156 public final int _length()
157 {
158 int c = 0;
159 for (LLCell p = this; p !is null; p = p.next_)
160 ++c;
161 return c;
162 }
163
164 /**
165 * return the cell representing the last element of the list
166 * (i.e., the one whose next() is null
167 **/
168
169 public final LLCell tail()
170 {
171 LLCell p = this;
172 for ( ; p.next_ !is null; p = p.next_)
173 {}
174 return p;
175 }
176
177 /**
178 * return the nth cell of the list, or null if no such
179 **/
180
181 public final LLCell nth(int n)
182 {
183 LLCell p = this;
184 for (int i = 0; i < n; ++i)
185 p = p.next_;
186 return p;
187 }
188
189
190 /**
191 * make a copy of the list; i.e., a new list containing new cells
192 * but including the same elements in the same order
193 **/
194
195 public final LLCell copyList()
196 {
197 LLCell newlist = null;
198 newlist = duplicate();
199 LLCell current = newlist;
200
201 for (LLCell p = next_; p !is null; p = p.next_)
202 {
203 current.next_ = p.duplicate();
204 current = current.next_;
205 }
206 current.next_ = null;
207 return newlist;
208 }
209
210 /**
211 * Clone is SHALLOW; i.e., just makes a copy of the current cell
212 **/
213
214 private final LLCell duplicate()
215 {
216 return new LLCell(element(), next_);
217 }
218
219 /**
220 * Basic linkedlist merge algorithm.
221 * Merges the lists head by fst and snd with respect to cmp
222 * @param fst head of the first list
223 * @param snd head of the second list
224 * @param cmp a Comparator used to compare elements
225 * Returns: the merged ordered list
226 **/
227
228 public final static LLCell merge(LLCell fst, LLCell snd, ComparatorT cmp)
229 {
230 LLCell a = fst;
231 LLCell b = snd;
232 LLCell hd = null;
233 LLCell current = null;
234 for (;;)
235 {
236 if (a is null)
237 {
238 if (hd is null)
239 hd = b;
240 else
241 current.next(b);
242 return hd;
243 }
244 else
245 if (b is null)
246 {
247 if (hd is null)
248 hd = a;
249 else
250 current.next(a);
251 return hd;
252 }
253
254 int diff = cmp.compare(a.element(), b.element());
255 if (diff <= 0)
256 {
257 if (hd is null)
258 hd = a;
259 else
260 current.next(a);
261 current = a;
262 a = a.next();
263 }
264 else
265 {
266 if (hd is null)
267 hd = b;
268 else
269 current.next(b);
270 current = b;
271 b = b.next();
272 }
273 }
274 return null;
275 }
276
277 /**
278 * Standard list splitter, used by sort.
279 * Splits the list in half. Returns the head of the second half
280 * @param s the head of the list
281 * Returns: the head of the second half
282 **/
283
284 public final static LLCell split(LLCell s)
285 {
286 LLCell fast = s;
287 LLCell slow = s;
288
289 if (fast is null || fast.next() is null)
290 return null;
291
292 while (fast !is null)
293 {
294 fast = fast.next();
295 if (fast !is null && fast.next() !is null)
296 {
297 fast = fast.next();
298 slow = slow.next();
299 }
300 }
301
302 LLCell r = slow.next();
303 slow.next(null);
304 return r;
305
306 }
307
308 /**
309 * Standard merge sort algorithm
310 * @param s the list to sort
311 * @param cmp, the comparator to use for ordering
312 * Returns: the head of the sorted list
313 **/
314
315 public final static LLCell mergeSort(LLCell s, ComparatorT cmp)
316 {
317 if (s is null || s.next() is null)
318 return s;
319 else
320 {
321 LLCell right = split(s);
322 LLCell left = s;
323 left = mergeSort(left, cmp);
324 right = mergeSort(right, cmp);
325 return merge(left, right, cmp);
326 }
327 }
328
329 }
330