SparseVector.hhnode
1 class SparseVector 2 { 3 private: 4 //結構體不必定會用到,不用初始化 5 struct node 6 { 7 int index; 8 int value; 9 node *next; 10 11 node(int index, int value, node *next = 0) : index(index), value(value), next(next) {} 12 }; 13 //這些纔是真正的數據成員,要初始化的 14 int size; 15 node *start; 16 17 void clear(); 18 void copyList(const SparseVector &sv); 19 void setNonzeroElem(int index, int value); 20 void removeElem(int index); 21 void checkListOrder(); 22 void addSubVector(const SparseVector &sv, bool add); 23 void removeZeros(); 24 void checkZeros(); 25 public: 26 SparseVector(int size); 27 const int getSize()const; 28 29 ~SparseVector(); 30 SparseVector(const SparseVector &sv); 31 SparseVector & operator= (const SparseVector &sv); 32 int getElem(int idx); 33 void setElem(int index, int value); 34 bool operator==(const SparseVector &sv)const; 35 bool operator!=(const SparseVector &sv)const; 36 SparseVector& operator+=(const SparseVector &sv); 37 SparseVector& operator-=(const SparseVector &sv); 38 const SparseVector& operator+(const SparseVector &sv)const; 39 const SparseVector& operator-(const SparseVector &sv)const; 40 };
SparseVector.ccios
1 #include "SparseVector.hh" 2 #include <cassert> 3 #include <iostream> 4 using namespace std; 5 //單參數構造函數 6 SparseVector::SparseVector(int size):size(size) 7 { 8 start = 0; 9 } 10 11 const int SparseVector::getSize()const 12 { 13 return size; 14 } 15 //成員函數都默認帶有this指針,因此默認對調用這個函數的對象進行操做,因此不用再傳本對象的地址了。 16 void SparseVector::clear() 17 { 18 node *next; 19 node *current; 20 current = start; 21 while(current != 0) 22 { 23 next = current->next; 24 delete current; 25 current = next; 26 } 27 start = 0; 28 } 29 //對本對象進行操做,調用成員行數也是默認對本對象進行操做,不用傳本對象地址。 30 SparseVector::~SparseVector() 31 { 32 clear(); 33 } 34 35 void SparseVector::copyList(const SparseVector &sv) 36 { 37 size = sv.getSize(); 38 node *current; 39 node *otherCurrent =sv.start; 40 node *prev = 0; 41 42 while(otherCurrent != 0) 43 { 44 current = new node(otherCurrent->index, otherCurrent->value); 45 if(prev == 0) 46 { 47 start = current; 48 prev = current; 49 } 50 prev->next = current; 51 prev = current; 52 otherCurrent = otherCurrent->next; 53 } 54 } 55 56 SparseVector::SparseVector(const SparseVector &sv) 57 { 58 copyList(sv); 59 } 60 //注意自賦值,而且直接調用私有幫助函數。 61 SparseVector & SparseVector:: operator= (const SparseVector &sv) 62 { 63 if (this == &sv) 64 { 65 return *this; 66 } 67 clear(); 68 copyList(sv); 69 return *this; 70 } 71 //難點 72 int SparseVector::getElem(int idx) 73 { 74 node *current = start; 75 while(current != 0 && current->index < idx)//過濾,兩個條件 76 { 77 current = current->next; 78 } 79 if(current == 0)//注意判斷條件前後次序,先排除current爲0狀況 80 { 81 return 0; 82 } 83 else if(current->index == idx)//若是先執行這個,則current爲0時,會直接產生段錯誤 84 { 85 return current->value; 86 } 87 else 88 { 89 return 0; 90 } 91 } 92 //難點,分種狀況討論:1,初始爲空。2,插到最後面。3,插到最前面。4,插到中間。 93 void SparseVector::setNonzeroElem(int index, int value) 94 { 95 assert(value != 0); 96 node *current = start; 97 node *prev = 0; 98 99 if(start == 0)//容易遺漏,鏈表初始爲空的狀況。(1) 100 { 101 start = new node(index, value); 102 } 103 else//除此狀況外(2,3,4) 104 { 105 while(current != 0 && current->index < index)//過濾,兩個條件,保證current指向應該指的結點,或其以後的結點。prev指向值小於應該的結點。 106 { 107 prev = current; 108 current = current->next;//別忘了自增 109 } 110 /*2選1 111 * if(current == start)//插到最前面,current所指結點大於等於它 112 { 113 if(current->index == index)//等於 114 { 115 current->value = value; 116 } 117 else//大於 118 { 119 node *other = new node(index, value, start); 120 start = other; 121 } 122 } 123 else if(current == 0)//插到最後面,current所指結點小於它 124 { 125 node *other = new node(index, value, 0); 126 prev->next = other; 127 } 128 else//插到中間,current所指結點大於等於它 129 { 130 if(current->index == index)//current所指結點等於它 131 { 132 current->value = value; 133 } 134 else//current所指結點結點大於它 135 { 136 node *other = new node(index, value, current); 137 prev->next = other; 138 } 139 } 140 */ 141 if(current == 0)//插到最後邊 142 { 143 node *other = new node(index, value); 144 prev->next = other; 145 } 146 else if(current -> index == index)//current所指結點等於它的值 147 { 148 current->value =value; 149 } 150 else if(current == start)//在最開始的地方 151 { 152 node *other = new node(index, value, start); 153 start = other; 154 } 155 else //在中間 156 { 157 node *other = new node(index, value, current); 158 prev->next = other; 159 } 160 } 161 } 162 163 void SparseVector::removeElem(int index) 164 { 165 node *current = start; 166 node *prev = 0; 167 while(current != 0 && current->index < index)//過濾 168 { 169 prev = current; 170 current = current->next; 171 } 172 if(current->index == index)//若是是這個結點 173 { 174 if(current == start)//是開始結點 175 { 176 prev = current; 177 current = current->next; 178 delete prev; 179 start = current; 180 return; 181 } 182 else//是中間結點或者是後邊的節點(相同的) 183 { 184 prev->next = current->next; 185 delete current; 186 return; 187 } 188 } 189 else 190 { 191 return; 192 } 193 } 194 195 void SparseVector::setElem(int index, int value) 196 { 197 if(value != 0) 198 { 199 setNonzeroElem(index, value); 200 } 201 else 202 { 203 removeElem(index); 204 } 205 } 206 207 void SparseVector::checkListOrder() 208 { 209 node *current = start; 210 while(current != 0) 211 { 212 cout<<"("<<current->index<<" | "<<current->value<<")"<<endl; 213 current = current->next; 214 } 215 return; 216 } 217 218 bool SparseVector::operator==(const SparseVector &sv)const 219 { 220 if(size != sv.size)//先判斷是否是size不等,直接排除 221 { 222 return false; 223 } 224 else//每一個結點依次判斷index和value 225 { 226 node *current = start; 227 node *otherCurrent = sv.start; 228 while(current != 0 && otherCurrent != 0) 229 { 230 if(current->index != otherCurrent->index || current->value != otherCurrent->value) 231 { 232 return false; 233 } 234 current = current->next; 235 otherCurrent = otherCurrent->next; 236 } 237 if(current == 0 && otherCurrent == 0)//看看還有沒有哪一個剩餘結點 238 { 239 return true; 240 } 241 else 242 { 243 return false; 244 } 245 } 246 } 247 248 bool SparseVector::operator!=(const SparseVector &sv)const 249 { 250 return !(*this == sv);//調用等號,結果取反 251 } 252 253 void SparseVector::addSubVector(const SparseVector &sv, bool add) 254 { 255 node *current = start; 256 node *otherCurrent = sv.start; 257 node *prev = 0; 258 int sign = (add ? 1 : -1);//注意符號處理方式 259 260 if(current == 0)//兩個鏈表合併時,必定不能忽略被合併鏈表爲空的狀況:(a+=b,其中a爲空) 261 { 262 if(otherCurrent == 0)//(ab均爲空) 263 { 264 return; 265 } 266 else 267 { 268 while(otherCurrent != 0)//(a爲空b不爲空)參考直接插入法造成一個新鏈表 269 { 270 node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, 0); 271 if(prev == 0) 272 { 273 start = addTo; 274 prev = addTo; 275 current = addTo; 276 } 277 else 278 { 279 current->next = addTo; 280 current = addTo; 281 } 282 otherCurrent = otherCurrent->next; 283 } 284 return; 285 } 286 } 287 else//合併時均非空的狀況 288 { 289 while(current != 0 && otherCurrent != 0)//都順序遍歷,直到某一鏈表結束 290 { 291 if(current->index > otherCurrent->index)//插入的 292 { 293 if(prev == 0)//初始結點 294 { 295 node *addTo = new node (otherCurrent->index, sign * otherCurrent->value, current); 296 start = addTo; 297 prev = addTo; 298 otherCurrent = otherCurrent->next; 299 } 300 else//非初始結點 301 { 302 node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, current); 303 prev->next = addTo; 304 prev = addTo; 305 otherCurrent = otherCurrent->next; 306 } 307 } 308 else if(current->index == otherCurrent->index)//直接加減的 309 { 310 current->value += sign * otherCurrent->value; 311 prev = current; 312 current = current->next; 313 otherCurrent = otherCurrent->next; 314 } 315 else if(current->index < otherCurrent->index)//不插入的 316 { 317 prev = current; 318 current = current->next; 319 } 320 } 321 if(otherCurrent == 0)//處理剩餘的結點 322 { 323 return; 324 } 325 else//把剩餘的插入到原來的 326 { 327 while(otherCurrent != 0) 328 { 329 node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, current); 330 prev->next = addTo; 331 prev = addTo; 332 otherCurrent = otherCurrent->next; 333 } 334 } 335 return; 336 } 337 } 338 339 void SparseVector::removeZeros() 340 { 341 node *current = start; 342 node *prev = 0; 343 while(current != 0)//非0狀態 344 { 345 if(current->value != 0) 346 { 347 prev = current; 348 current = current->next; 349 } 350 else//爲0狀態 351 { 352 if(prev == 0)//若是初始結點爲0 353 { 354 prev = current; 355 current = current->next; 356 delete prev; 357 start = current; 358 prev = 0; 359 } 360 else//非初始結點爲0 361 { 362 node *temp = current; 363 current = current->next; 364 delete temp; 365 prev->next = current; 366 } 367 } 368 } 369 } 370 371 SparseVector& SparseVector::operator+=(const SparseVector &sv) 372 { 373 addSubVector(sv, true); 374 removeZeros(); 375 node * current = start; 376 size = 0; 377 while(current != 0)//最後還要把size弄好 378 { 379 ++size; 380 current = current->next; 381 } 382 return *this; 383 } 384 385 SparseVector& SparseVector::operator-=(const SparseVector &sv) 386 { 387 addSubVector(sv, false); 388 removeZeros(); 389 size = 0; 390 node *current = start; 391 while(current != 0)//最後還要把size弄好 392 { 393 ++size; 394 current = current->next; 395 } 396 return *this; 397 } 398 399 const SparseVector& SparseVector::operator+(const SparseVector &sv)const 400 { 401 SparseVector *newSp = new SparseVector(*this); 402 *newSp += sv; 403 return *newSp; 404 } 405 406 const SparseVector& SparseVector::operator-(const SparseVector &sv)const 407 { 408 SparseVector *newSp = new SparseVector(*this); 409 *newSp -= sv; 410 return *newSp; 411 } 412 413 void SparseVector::checkZeros() 414 { 415 node *current = start; 416 while(current != 0) 417 { 418 if(current->value == 0) 419 { 420 cout<<"number "<<current->index<<" "<<current->value<<endl; 421 current = current->next; 422 } 423 } 424 }