/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * SimpleLinkedList.java * Copyright (C) 2003 Peter A. Flach, Nicolas Lachiche * * Thanks to Amelie Deltour for porting the original C code to Java * and integrating it into Weka. */ package weka.associations.tertius; import weka.core.RevisionHandler; import weka.core.RevisionUtils; import java.io.Serializable; import java.util.Comparator; import java.util.NoSuchElementException; /** * @author Peter A. Flach * @author Nicolas Lachiche * @version $Revision: 1.6 $ */ public class SimpleLinkedList implements Serializable, RevisionHandler { /** for serialization */ private static final long serialVersionUID = -1491148276509976299L; public class LinkedListIterator implements Serializable, RevisionHandler { /** for serialization */ private static final long serialVersionUID = -2448555236100426759L; Entry current = first; Entry lastReturned = null; public boolean hasNext() { return current.next != last; } public Object next() { if (current == last) { throw new NoSuchElementException(); } current = current.next; lastReturned = current; return current.element; } public void remove() { if (lastReturned == last || lastReturned == null) { throw new IllegalStateException(); } lastReturned.previous.next = lastReturned.next; lastReturned.next.previous = lastReturned.previous; current = lastReturned.previous; lastReturned = null; } public void addBefore(Object o) { if (lastReturned == null) { throw new IllegalStateException(); } Entry newEntry = new Entry(o, lastReturned, lastReturned.previous); lastReturned.previous.next = newEntry; lastReturned.previous = newEntry; } /** * Returns the revision string. * * @return the revision */ public String getRevision() { return RevisionUtils.extract("$Revision: 1.6 $"); } } public class LinkedListInverseIterator implements Serializable, RevisionHandler { /** for serialization */ private static final long serialVersionUID = 6290379064027832108L; Entry current = last; Entry lastReturned = null; public boolean hasPrevious() { return current.previous != first; } public Object previous() { if (current == first) { throw new NoSuchElementException(); } current = current.previous; lastReturned = current; return current.element; } public void remove() { if (lastReturned == first || lastReturned == null) { throw new IllegalStateException(); } lastReturned.previous.next = lastReturned.next; lastReturned.next.previous = lastReturned.previous; current = lastReturned.next; lastReturned = null; } /** * Returns the revision string. * * @return the revision */ public String getRevision() { return RevisionUtils.extract("$Revision: 1.6 $"); } } private static class Entry implements Serializable, RevisionHandler { /** for serialization */ private static final long serialVersionUID = 7888492479685339831L; Object element; Entry next; Entry previous; Entry(Object element, Entry next, Entry previous) { this.element = element; this.next = next; this.previous = previous; } /** * Returns the revision string. * * @return the revision */ public String getRevision() { return RevisionUtils.extract("$Revision: 1.6 $"); } } private Entry first; private Entry last; public SimpleLinkedList() { first = new Entry(null, null, null); last = new Entry(null, null, null); first.next = last; last.previous = first; } public Object removeFirst() { if (first.next == last) { throw new NoSuchElementException(); } Object result = first.next.element; first.next.next.previous = first; first.next = first.next.next; return result; } public Object getFirst() { if (first.next == last) { throw new NoSuchElementException(); } return first.next.element; } public Object getLast() { if (last.previous == first) { throw new NoSuchElementException(); } return last.previous.element; } public void addFirst(Object o) { Entry newEntry = new Entry(o, first.next, first); first.next.previous = newEntry; first.next = newEntry; } public void add(Object o) { Entry newEntry = new Entry(o, last, last.previous); last.previous.next = newEntry; last.previous = newEntry; } public void addAll(SimpleLinkedList list) { last.previous.next = list.first.next; list.first.next.previous = last.previous; last = list.last; } public void clear() { first.next = last; last.previous = first; } public boolean isEmpty() { return first.next == last; } public LinkedListIterator iterator() { return new LinkedListIterator(); } public LinkedListInverseIterator inverseIterator() { return new LinkedListInverseIterator(); } public int size() { int result = 0; LinkedListIterator iter = new LinkedListIterator(); while (iter.hasNext()) { result++; iter.next(); } return result; } public void merge(SimpleLinkedList list, Comparator comp) { LinkedListIterator iter1 = this.iterator(); LinkedListIterator iter2 = list.iterator(); Object elem1 = iter1.next(); Object elem2 = iter2.next(); while (elem2 != null) { if ((elem1 == null) || (comp.compare(elem2, elem1) < 0)) { iter1.addBefore(elem2); elem2 = iter2.next(); } else { elem1 = iter1.next(); } } } public void sort(Comparator comp) { LinkedListIterator iter = this.iterator(); if (iter.hasNext()) { SimpleLinkedList lower = new SimpleLinkedList(); SimpleLinkedList upper = new SimpleLinkedList(); Object ref = iter.next(); Object elem; while (iter.hasNext()) { elem = iter.next(); if (comp.compare(elem, ref) < 0) { lower.add(elem); } else { upper.add(elem); } } lower.sort(comp); upper.sort(comp); clear(); addAll(lower); add(ref); addAll(upper); } } public String toString() { StringBuffer text = new StringBuffer(); LinkedListIterator iter = iterator(); text.append("["); while (iter.hasNext()) { text.append(String.valueOf(iter.next())); if (iter.hasNext()) { text.append(", "); } } text.append("]"); return text.toString(); } /** * Save the state of this <tt>LinkedList</tt> instance to a stream (that * is, serialize it). * * @serialData The size of the list (the number of elements it * contains) is emitted (int), followed by all of its * elements (each an Object) in the proper order. */ private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out size s.writeInt(size()); // Write out all elements in the proper order. for (Entry e = first.next; e != last; e = e.next) s.writeObject(e.element); } /** * Reconstitute this <tt>LinkedList</tt> instance from a stream (that is * deserialize it). */ private synchronized void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in size int size = s.readInt(); // Initialize header first = new Entry(null, null, null); last = new Entry(null, null, null); first.next = last; last.previous = first; // Read in all elements in the proper order. for (int i=0; i<size; i++) add(s.readObject()); } /** * Returns the revision string. * * @return the revision */ public String getRevision() { return RevisionUtils.extract("$Revision: 1.6 $"); } }