SparseVector.hh
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.cc
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 }