You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SkipList.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. package common;
  2. import java.lang.reflect.Array;
  3. import java.util.*;
  4. /**
  5. * Class SkipList implements a skip list that uses int primitives for
  6. * the element keys. The modification methods defined by <code>Set</code>
  7. * are not supported. Instead, methods with keys are required. Note that
  8. * the keys have a many to one relationship with the elements (that is,
  9. * a range of key values will map to a single element).
  10. *
  11. * <p><b>Note that this implementation is not synchronized.</b> If multiple
  12. * threads access a set concurrently, and at least one of the threads modifies
  13. * the set, it <i>must</i> be synchronized externally. This is typically
  14. * accomplished by synchronizing on some object that naturally encapsulates
  15. * the set. If no such object exists, the set should be "wrapped" using the
  16. * <code>Collections.synchronizedList</code> method. This is best done at
  17. * creation time, to prevent accidental unsynchronized access to the set:</p>
  18. *<pre>
  19. * List l = Collections.synchronizedList(new DisjointSet(...));
  20. *</pre>
  21. *
  22. * <p>The Iterators returned by this class's <tt>iterator</tt> method are
  23. * <i>fail-fast</i>: if the set is modified at any time after the iterator is
  24. * created, in any way except through the iterator's own <tt>remove</tt>
  25. * method, the iterator will throw a <tt>ConcurrentModificationException</tt>.
  26. * Thus, in the face of concurrent modification, the iterator fails quickly
  27. * and cleanly, rather than risking arbitrary, non-deterministic behavior at
  28. * an undetermined time in the future.</p>
  29. *
  30. * @author Original version: Nathan Fiedler (2001)
  31. * @author Several important bugfixes: Holger Hoffstaette
  32. *
  33. * @version $Revision$ $Date$
  34. */
  35. public class SkipList<T extends Comparable> extends Object implements Set<T>, Iterable<T>
  36. {
  37. /** Optimal probability of most skip lists. */
  38. public static final double OPTIMAL_P = 0.25;
  39. // MaxLevel = L(N) (where N is an upper bound on the number of
  40. // elements in a skip list). If p = 0.5, using MaxLevel = 16 is
  41. // appropriate for data structures containing up to 2^16 elements.
  42. /** Maximum level of any SkipList instance. */
  43. protected final int MAX_LEVEL;
  44. /** Probability value for this skip list. */
  45. protected final double P;
  46. /** Tail of this skip list. */
  47. protected final SkipListElement<T> _NIL;
  48. /** The level of this skip list. */
  49. protected int _listLevel;
  50. /** Header is an element with no data. */
  51. protected SkipListElement<T> _listHeader;
  52. /** Number of elements in this skip list. */
  53. protected int _elementCount;
  54. /** Increments each time the list changes. */
  55. protected int _modCount;
  56. /**
  57. * Constructs an empty SkipList using the default probability
  58. * and maximum element size.
  59. */
  60. public SkipList()
  61. {
  62. this(OPTIMAL_P, (int)Math.ceil(Math.log(Integer.MAX_VALUE) / Math.log(1 / OPTIMAL_P)) - 1);
  63. }
  64. /**
  65. * Constructs an empty SkipList object using the given probability
  66. * and maximum level.
  67. *
  68. * @param probability skip list probability value.
  69. * @param maxLevel maximum skip list level.
  70. */
  71. public SkipList(double probability, int maxLevel)
  72. {
  73. P = probability;
  74. MAX_LEVEL = maxLevel;
  75. // Header is the root of our skip list.
  76. _listHeader = new SkipListElement<T>(MAX_LEVEL, Integer.MIN_VALUE, null);
  77. // Allocate NIL with a key greater than any valid key;
  78. // all levels of skip lists terminate on NIL.
  79. _NIL = new SkipListElement<T>(0, Integer.MAX_VALUE, null);
  80. this.clear();
  81. }
  82. public SkipList(Collection<? extends T> c)
  83. {
  84. this();
  85. this.addAll(c);
  86. }
  87. public boolean add(T o)
  88. {
  89. this.insert(o.hashCode(), o);
  90. return true;
  91. }
  92. public boolean addAll(Collection<? extends T> c)
  93. {
  94. boolean added = false;
  95. if (!c.isEmpty())
  96. {
  97. for (Iterator<? extends T> iter = c.iterator(); iter.hasNext();)
  98. {
  99. added |= this.add(iter.next());
  100. }
  101. }
  102. return added;
  103. }
  104. public void clear()
  105. {
  106. // List level is started at one.
  107. _listLevel = 1;
  108. // All forward pointers of list's header point to NIL.
  109. for (int i = _listHeader._forward.length - 1; i >= 0; i--)
  110. {
  111. _listHeader._forward[i] = _NIL;
  112. }
  113. // Reset element count.
  114. _elementCount = 0;
  115. _modCount++;
  116. }
  117. public boolean contains(Object o)
  118. {
  119. for (SkipListElement e = _listHeader._forward[0]; e != _NIL; e = e._forward[0])
  120. {
  121. if ((e._value == o) || e._value != null && e._value.equals(o))
  122. {
  123. return true;
  124. }
  125. }
  126. return false;
  127. }
  128. public boolean containsAll(Collection<?> c)
  129. {
  130. if ((this.size() < c.size()) || (this.isEmpty() && c.isEmpty()))
  131. {
  132. return false;
  133. }
  134. for (Iterator<?> iter = c.iterator(); iter.hasNext();)
  135. {
  136. if (!this.contains(iter.next()))
  137. {
  138. return false;
  139. }
  140. }
  141. return true;
  142. }
  143. /**
  144. * Removes the element with the given key from the list.
  145. *
  146. * @param searchKey key of element to remove.
  147. * @return <code>true</code> if element was found and removed.
  148. */
  149. public boolean remove(int searchKey)
  150. {
  151. SkipListElement[] update = new SkipListElement[MAX_LEVEL];
  152. SkipListElement e = _listHeader;
  153. for (int i = _listLevel; i >= 0; i--)
  154. {
  155. while (e._forward[i]._key < searchKey)
  156. {
  157. e = e._forward[i];
  158. }
  159. update[i] = e;
  160. }
  161. e = e._forward[0];
  162. if (e._key == searchKey)
  163. {
  164. for (int i = 0; i < _listLevel; i++)
  165. {
  166. if (update[i]._forward[i] != e)
  167. {
  168. break;
  169. }
  170. update[i]._forward[i] = e._forward[i];
  171. }
  172. while (_listLevel > 0 && _listHeader._forward[_listLevel] == _NIL)
  173. {
  174. _listLevel--;
  175. }
  176. _elementCount--;
  177. _modCount++;
  178. return true;
  179. }
  180. return false;
  181. }
  182. /**
  183. * Inserts the element using the given search key. If an element
  184. * with the same key already exists in the skip lists, its value
  185. * will be replaced with <code>newValue</code>.
  186. *
  187. * @param searchKey key for element.
  188. * @param newValue new element to insert.
  189. */
  190. @SuppressWarnings("unchecked")
  191. public void insert(int searchKey, T newValue)
  192. {
  193. SkipListElement<T>[] update = new SkipListElement[MAX_LEVEL];
  194. SkipListElement<T> e = _listHeader;
  195. for (int i = _listLevel - 1; i >= 0; i--)
  196. {
  197. while (e._forward[i]._key < searchKey)
  198. {
  199. e = e._forward[i];
  200. }
  201. update[i] = e;
  202. }
  203. e = e._forward[0];
  204. if (e._key == searchKey)
  205. {
  206. e._value = newValue;
  207. }
  208. else
  209. {
  210. int lvl = randomLevel();
  211. if (lvl > _listLevel)
  212. {
  213. for (int i = _listLevel; i <= lvl; i++)
  214. {
  215. update[i] = _listHeader;
  216. }
  217. _listLevel = lvl;
  218. }
  219. e = new SkipListElement<T>(lvl, searchKey, newValue);
  220. for (int i = 0; i < lvl; i++)
  221. {
  222. e._forward[i] = update[i]._forward[i];
  223. update[i]._forward[i] = e;
  224. }
  225. }
  226. _elementCount++;
  227. _modCount++;
  228. }
  229. public boolean isEmpty()
  230. {
  231. return (_elementCount == 0);
  232. }
  233. public Iterator<T> iterator()
  234. {
  235. return new SkipListIterator<T>();
  236. }
  237. /**
  238. * Return a random level.
  239. *
  240. * @return level selected randomly.
  241. */
  242. protected int randomLevel()
  243. {
  244. int lvl = 1;
  245. while (lvl < MAX_LEVEL && Math.random() < P)
  246. {
  247. lvl++;
  248. }
  249. return lvl;
  250. }
  251. public boolean remove(Object o)
  252. {
  253. return this.remove(o.hashCode());
  254. }
  255. public boolean removeAll(Collection c)
  256. {
  257. boolean removed = false;
  258. for (Iterator iter = c.iterator(); iter.hasNext();)
  259. {
  260. removed |= this.remove(iter.next());
  261. }
  262. return removed;
  263. }
  264. public boolean retainAll(Collection c)
  265. {
  266. throw new UnsupportedOperationException();
  267. }
  268. /**
  269. * Searches for the element with the given key.
  270. *
  271. * @param searchKey key to look for.
  272. * @return element if found, null if not found. Note that you may
  273. * not want to store nulls in this list as it would then
  274. * be difficult to know the difference.
  275. */
  276. public T get(int searchKey)
  277. {
  278. SkipListElement<T> e = _listHeader;
  279. for (int i = _listLevel - 1; i >= 0; i--)
  280. {
  281. while (e._forward[i]._key < searchKey)
  282. {
  283. e = e._forward[i];
  284. }
  285. }
  286. e = e._forward[0];
  287. if (e._key == searchKey)
  288. {
  289. return e._value;
  290. }
  291. else
  292. {
  293. return null;
  294. }
  295. }
  296. /**
  297. * Searches for the element with a key that is the least smaller
  298. * value of the given key.
  299. *
  300. * @param searchKey key to look for.
  301. * @return element if found, null if not found.
  302. */
  303. public T searchLeastSmaller(int searchKey)
  304. {
  305. SkipListElement<T> e = _listHeader;
  306. for (int i = _listLevel - 1; i >= 0; i--)
  307. {
  308. while (e._forward[i]._key < searchKey)
  309. {
  310. e = e._forward[i];
  311. }
  312. }
  313. if (e._forward[0]._key == searchKey)
  314. {
  315. return e._forward[0]._value;
  316. }
  317. else
  318. {
  319. return e._value;
  320. }
  321. }
  322. /**
  323. * Searches for the element just after the one found using the
  324. * given key (where the key value may be the least smaller of
  325. * the given key).
  326. *
  327. * @param searchKey key to look for.
  328. * @return next element if found, null if not found.
  329. */
  330. public T searchNextLarger(int searchKey)
  331. {
  332. SkipListElement<T> e = _listHeader;
  333. for (int i = _listLevel - 1; i >= 0; i--)
  334. {
  335. while (e._forward[i]._key < searchKey)
  336. {
  337. e = e._forward[i];
  338. }
  339. }
  340. SkipListElement<T> t = null;
  341. if (e._forward[0]._key == searchKey)
  342. {
  343. t = e._forward[0];
  344. }
  345. else
  346. {
  347. t = e;
  348. }
  349. if (t._forward[0] == _NIL)
  350. {
  351. return null;
  352. }
  353. else
  354. {
  355. return t._forward[0]._value;
  356. }
  357. }
  358. /**
  359. * Returns the number of elements in this list. If this list contains
  360. * more than <tt>Integer.MAX_VALUE</tt> elements, returns
  361. * <tt>Integer.MAX_VALUE</tt>.
  362. *
  363. * @return the number of elements in this list.
  364. */
  365. public int size()
  366. {
  367. return _elementCount;
  368. }
  369. /**
  370. * Returns an array containing all of the elements in this list in
  371. * proper sequence. Obeys the general contract of the
  372. * <tt>Collection.toArray()</tt> method.
  373. *
  374. * @return an array containing all of the elements in this list in
  375. * proper sequence.
  376. * @see Arrays#asList(Object[])
  377. */
  378. public Object[] toArray()
  379. {
  380. return toArray(new Object[_elementCount]);
  381. }
  382. /**
  383. * Returns an array containing all of the elements in this list in
  384. * proper sequence; the runtime type of the returned array is that
  385. * of the specified array. Obeys the general contract of the
  386. * <tt>Collection.toArray(Object[])</tt> method.
  387. *
  388. * @param a the array into which the elements of this list are to
  389. * be stored, if it is big enough; otherwise, a new array
  390. * of the same runtime type is allocated for this purpose.
  391. * @return an array containing the elements of this list.
  392. * @exception ArrayStoreException
  393. * Throw if the runtime type of the specified array is not
  394. * a supertype of the runtime type of every element in this
  395. * list.
  396. */
  397. @SuppressWarnings({"unchecked","hiding"})
  398. public <T> T[] toArray(T[] a)
  399. {
  400. int size = this.size();
  401. if (a.length < size)
  402. {
  403. a = (T[])Array.newInstance(a.getClass().getComponentType(), size);
  404. }
  405. SkipListElement e = _listHeader;
  406. for (int i = 0; i < _elementCount; i++)
  407. {
  408. a[i] = (T)e._forward[0]._value;
  409. e = e._forward[0];
  410. }
  411. return a;
  412. }
  413. /**
  414. * Class Element represents an element of a skip list.
  415. */
  416. protected class SkipListElement<E> extends Object
  417. {
  418. /** Key of element. */
  419. int _key;
  420. /** Value of element. */
  421. E _value;
  422. /** List of forward pointers. */
  423. SkipListElement<E>[] _forward;
  424. /**
  425. * Constructs an Element for the given key and value.
  426. *
  427. * @param level level for this node (number of forward pointers).
  428. * @param key key for element.
  429. * @param value value for element.
  430. */
  431. @SuppressWarnings("unchecked")
  432. public SkipListElement(int level, int key, E value)
  433. {
  434. _key = key;
  435. _value = value;
  436. _forward = new SkipListElement[level];
  437. }
  438. }
  439. /**
  440. * An iterator over a skip list.
  441. */
  442. protected class SkipListIterator<E> implements Iterator<T>
  443. {
  444. /** Index into the skip list. */
  445. protected int _index;
  446. /** The modCount of the list at the time we were instantiated. */
  447. protected int _listModCount;
  448. /** Current element being examined. */
  449. protected SkipListElement<T> _elem;
  450. /**
  451. * Constructs a skip list iterator.
  452. */
  453. public SkipListIterator()
  454. {
  455. _listModCount = SkipList.this._modCount;
  456. _elem = _listHeader;
  457. }
  458. /**
  459. * Returns <tt>true</tt> if the iteration has more elements. (In
  460. * other words, returns <tt>true</tt> if <tt>next</tt> would return
  461. * an element rather than throwing an exception.)
  462. *
  463. * @return <tt>true</tt> if the iterator has more elements.
  464. */
  465. public boolean hasNext()
  466. {
  467. if (this._listModCount != SkipList.this._modCount)
  468. {
  469. throw new ConcurrentModificationException();
  470. }
  471. return _elem._forward[0] != _NIL;
  472. }
  473. /**
  474. * Returns the next element in the iteration.
  475. *
  476. * @return the next element in the iteration.
  477. * @exception NoSuchElementException
  478. * iteration has no more elements.
  479. */
  480. public T next()
  481. {
  482. if (this._listModCount != SkipList.this._modCount)
  483. {
  484. throw new ConcurrentModificationException();
  485. }
  486. if (this.hasNext())
  487. {
  488. _elem = _elem._forward[0];
  489. return _elem._value;
  490. }
  491. else
  492. {
  493. throw new NoSuchElementException();
  494. }
  495. }
  496. public void remove()
  497. {
  498. throw new UnsupportedOperationException();
  499. }
  500. }
  501. }