Grafalgo
Library of useful data structures and algorithms
|
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