Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/dataStructures/basic/List.cpp
Go to the documentation of this file.
00001 
00009 #include "List.h"
00010 
00011 namespace grafalgo {
00012 
00014 List::List(int nn1) : Adt(nn1), len(0) {
00015         try { makeSpace(n()); } catch(OutOfSpaceException e) {
00016                 string s; s = "List::" + e.toString(s);
00017                 throw OutOfSpaceException(s);
00018         }
00019 }
00020 
00022 List::~List() { freeSpace(); }
00023 
00027 void List::makeSpace(int size) {
00028         try { nxt = new index[size+1]; } catch (std::bad_alloc e) {
00029                 stringstream ss;
00030                 ss << "makeSpace:: insufficient space for "
00031                    << size << "index values";
00032                 string s = ss.str();
00033                 throw OutOfSpaceException(s);
00034         }
00035         for (index i = 1; i <= size; i++) nxt[i] = -1;
00036         nxt[0] = 0; head = tail = 0;
00037         nn = size; len = 0;
00038 }
00039 
00041 void List::freeSpace() { delete [] nxt; }
00042 
00044 void List::copyFrom(const List& source) {
00045         if (&source == this) return;
00046         if (source.n() > n()) resize(source.n());
00047         else clear();
00048         for (index x = source.first(); x != 0; x = source.next(x))
00049                 addLast(x);
00050 }
00051 
00056 void List::resize(int size) {
00057         freeSpace();
00058         try { makeSpace(size); } catch(OutOfSpaceException e) {
00059                 string s; s = "List::resize::" + e.toString(s);
00060                 throw OutOfSpaceException(s);
00061         }
00062 }
00063 
00068 void List::expand(int size) {
00069         if (size <= n()) return;
00070         List old(this->n()); old.copyFrom(*this);
00071         resize(size); this->copyFrom(old);
00072 }
00073 
00075 void List::clear() { while (!empty()) removeFirst(); }
00076 
00082 index List::get(position i) const {
00083         if (i < 1 || i > length()) return 0;
00084         if (i == 1) return first();
00085         index j;
00086         for (j = first(); j != 0 && --i; j = nxt[j]) {}
00087         return j;
00088 }
00089 
00097 bool List::insert(index i, index j) {
00098         if (!((i == 0 || valid(i)) && (j == 0 || valid(j)))) {
00099                 stringstream ss;
00100                 ss << "List::insert(" << i << "," << j << ")";
00101                 string s = ss.str();
00102                 throw IllegalArgumentException(s);
00103         }
00104         if (i == 0 || member(i)) return false;
00105         len++;
00106         if (j == 0) {
00107                 if (empty()) tail = i;
00108                 nxt[i] = head; head = i;
00109                 return true;
00110         }
00111         nxt[i] = nxt[j]; nxt[j] = i;
00112         if (tail == j) tail = i;
00113         return true;
00114 }
00115 
00121 bool List::removeNext(index i) {
00122         if (i < 0 || i > n()) {
00123                 stringstream ss;
00124                 ss << "List::removeNext(" << i << ")";
00125                 string s = ss.str();
00126                 throw IllegalArgumentException(s);
00127         }
00128         if (empty() || (i == last()) || (i != 0 && !member(i)))
00129                 return false;
00130         index j;
00131         if (i == 0) { j = head;   head = nxt[j]; }
00132         else        { j = nxt[i]; nxt[i] = nxt[j]; }
00133         if (tail == j) tail = i;
00134         nxt[j] = -1;
00135         len--;
00136         return true;
00137 }
00138 
00146 bool List::equals(List& other) const {
00147         if (this == &other) return true;
00148         if (this->length() != other.length()) return false;
00149         index i = first(); index j = other.first();
00150         while (i == j) {
00151                 if (i == 0) return true;
00152                 i = next(i); j = other.next(j);
00153         }
00154         return false;
00155 }
00156 
00160 bool List::isConsistent() const {
00161         if (head < 0 || head > n()) return false;
00162         if (tail < 0 || tail > n()) return false;
00163         if ((head == 0 || tail == 0) && head != tail) return false;
00164         int cnt = 0;
00165         for (int i = first(); i != 0; i = next(i)) {
00166                 if (i < 0 || i > n()) return false;
00167                 if (i == tail &&  next(i) != 0) return false;
00168                 if (++cnt > length()) return false;
00169         }
00170         if (cnt != length()) return false;
00171         for (int i = 1; i <= n(); i++) if (nxt[i] == -1) cnt++;
00172         if (cnt != n()) return false;
00173         if (nxt[0] != 0) return false;
00174         return true;
00175 }
00176 
00181 string& List::toString(string& s) const {
00182         s = "[";
00183         bool isFirst = true;
00184         for (index i = first(); i != 0; i = next(i)) {
00185                 if (isFirst) isFirst = false;
00186                 else s += " ";
00187                 string s1; s += item2string(i,s1);
00188         }
00189         s += "]";
00190         return s;
00191 }
00192 
00193 istream& operator>>(istream& in, List& lst) {
00194         lst.clear();
00195         if (!Util::verify(in,'[')) return in;
00196         while (true) {
00197                 Util::skipSpace(in);
00198                 char c = in.peek();
00199                 if (!in.good()) {
00200                         string s = "List::operator>>: misformatted list";
00201                         throw InputException(s);
00202                 }
00203                 index x;
00204                 if (c == ']') {
00205                         c = in.get(); return in;
00206                 } else if (isalpha(c)) {
00207                         x = (c - 'a') + 1; c = in.get();
00208                 } else if (isdigit(c)) {
00209                         in >> x;
00210                 } else {
00211                         string s = "List::operator>>: unexpected input "
00212                                    "character " + c;
00213                         throw InputException(s);
00214                 }
00215                 if (lst.n() < x) lst.expand(max(x,2*lst.n()));
00216                 if (lst.member(x)) {
00217                         string s = "List::operator>>: repeated element in list";
00218                         throw InputException(s);
00219                 }
00220                 lst.addLast(x);
00221         }
00222 }
00223 
00224 } // ending namespace
 All Classes Files Functions Variables Typedefs Friends