1. 程式人生 > >多重鄰接表操作實現

多重鄰接表操作實現

多重鄰接表是一種比較重要的無向簡單圖儲存結構,鑑於無向圖在資料結構課程中的重要性,多重鄰接表操作實現必須要予以解決。圖論及其演算法在編譯原理中具有很重要的地位,圖著色的暫存器分配就要用到無向簡單圖,所以自己嘗試實現一下鄰接多重表的操作。

一開始很天真的以為鄰接多重表的實現難度和十字連結串列應該相差不大,十字連結串列能夠實現鄰接多重表應該也不成問題,但實際開始動手後才發現情況並非如此,鄰接多重表實現比十字連結串列更為複雜。不得不承認自己實在太笨,問題沒考慮全面就急匆匆敲程式碼,結果執行後不是發現這裡沒考慮到就是那裡存在錯誤,於是就反反覆覆修改編譯修改編譯,真是被折磨死了。圖結構及其演算法確實是資料結構中最難的部分之一,我已經深有體會了。用了整整兩天時間總算正確實現了鄰接多重表的操作,實現了新增邊,刪除邊,刪除頂點,複製,合併,銷燬,新增頂點這些重要的API,其他介面應該沒有那麼重要,需要的話以後還可以新增。

C++程式碼清單:

 

  1 #include "pch.h"
  2 #include <iostream>
  3 #include <vector>
  4 #include <set>
  5 using namespace std;
  6 
  7 template <typename V, typename E>
  8 class Graph   //無向簡單圖類,儲存結構為多重鄰接表
  9 {
 10     friend vector<vector<int>> *convertToAdjaMatrix(Graph<size_t, size_t> *undigraph);
11 public: 12 struct VertexNode; 13 struct EdgeNode //邊節點型別 14 { 15 E *edge_data_field = nullptr; //邊節點資料域 16 typename vector<VertexNode *>::size_type left = 0; //邊一端對應頂點 17 typename vector<VertexNode *>::size_type right = 0; //邊另一端對應頂點 18 EdgeNode *same_left_ptr = nullptr; //
指向一端仍為left的下一個邊節點的指標 19 EdgeNode *same_right_ptr = nullptr; //指向另一端仍為right的下一個邊節點的指標 20 EdgeNode() = default; 21 EdgeNode(typename vector<VertexNode *>::size_type l, typename vector<VertexNode *>::size_type r, E *e) :left(l), right(r), edge_data_field(e) {} 22 ~EdgeNode() { delete edge_data_field; } 23 }; 24 25 struct VertexNode //頂點節點 26 { 27 V *vertex_data_field = nullptr; //頂點資料域 28 typename vector<VertexNode *>::size_type number = 0; //頂點編號 29 EdgeNode *first_ptr = nullptr; //指向和該頂點關聯的第一條邊的指標 30 VertexNode *seilring = nullptr; //指向當前頂點,表示存在自環 31 E *Edgeseilring = nullptr; //自環邊 32 33 VertexNode() = default; 34 VertexNode(typename vector<VertexNode *>::size_type n, V *v) :number(n), vertex_data_field(v) {} 35 ~VertexNode() { delete vertex_data_field; delete Edgeseilring; } 36 }; 37 38 Graph() = default; 39 Graph(typename vector<VertexNode *>::size_type n) :set_of_vertex(n, nullptr) {} 40 virtual ~Graph(); //釋放多重鄰接表並銷燬圖 41 Graph<V, E> *copy(); //拷貝當前無向圖並返回指向副本的指標 42 typename vector<typename VertexNode *>::size_type addVertex(V *vertex); //新增頂點,vertex為頂點資料域 43 bool addEdge(typename vector<VertexNode *>::size_type left, typename vector<VertexNode *>::size_type right, E *edge); //新增邊(left, right),edge為邊資料域 44 void deleteVertex(typename vector<VertexNode *>::size_type vertex); //刪除頂點vertex 45 bool deleteEdge(typename vector<VertexNode *>::size_type left, typename vector<VertexNode *>::size_type right); //刪除邊(left, right) 46 Graph<V, E> *merge(Graph<V, E>& Bemerged, bool copyOrNot); //將Bemerged和當前無向圖合併,copyOrNot=true拷貝當前圖返回合併後得到的新的無向圖的指標,=false直接合並至當前圖返回空指標 47 typename vector<VertexNode *>::size_type getVertexNum() { return set_of_vertex.size(); } //獲取無向圖中頂點數目 48 protected: 49 vector<VertexNode *> set_of_vertex; //無向圖頂點集 50 }; 51 52 template <typename V, typename E> 53 typename vector<typename Graph<V, E>::VertexNode *>::size_type Graph<V, E>::addVertex(V *vertex) 54 { 55 set_of_vertex.push_back(new VertexNode(set_of_vertex.size(), vertex)); 56 return set_of_vertex.size() - 1; 57 58 } 59 60 template <typename V, typename E> 61 bool Graph<V, E>::addEdge(typename vector<VertexNode *>::size_type left, typename vector<VertexNode *>::size_type right, E *edge) //從left和right頂點節點開始檢索插入位置並插入,該過程會保持和left或right關聯的邊節點的另一端頂點的編號的有序性(從小到大) 62 { 63 if (left >= set_of_vertex.size() || right >= set_of_vertex.size()) 64 { 65 throw new out_of_range("無效的頂點引數\\n"); 66 } 67 if (left == right) 68 { 69 set_of_vertex[left]->seilring = set_of_vertex[left]; 70 set_of_vertex[left]->Edgeseilring = new E(*edge); 71 return true; 72 } 73 74 EdgeNode *start = set_of_vertex[left]->first_ptr; 75 EdgeNode *pre = nullptr; 76 if (start == nullptr) 77 { 78 set_of_vertex[left]->first_ptr = new EdgeNode(left, right, edge); 79 if (set_of_vertex[right]->first_ptr == nullptr) 80 { 81 set_of_vertex[right]->first_ptr = set_of_vertex[left]->first_ptr; 82 return true; 83 } 84 } 85 else 86 { 87 for (; start != nullptr; ) 88 { 89 if ((start->left == left ? start->right : start->left) == right) 90 return false; 91 else if ((start->left == left ? start->right : start->left) < right) 92 { 93 pre = start; 94 if (start->left == left) 95 { 96 start = start->same_left_ptr; 97 } 98 else 99 { 100 start = start->same_right_ptr; 101 } 102 } 103 else 104 { 105 if (pre == nullptr) 106 { 107 pre = set_of_vertex[left]->first_ptr; 108 set_of_vertex[left]->first_ptr = new EdgeNode(left, right, edge); 109 set_of_vertex[left]->first_ptr->same_left_ptr = pre; 110 if (set_of_vertex[right]->first_ptr == nullptr) 111 { 112 set_of_vertex[right]->first_ptr = set_of_vertex[left]->first_ptr; 113 return true; 114 } 115 pre = set_of_vertex[left]->first_ptr; 116 } 117 else 118 { 119 if (pre->left == left) 120 { 121 pre->same_left_ptr = new EdgeNode(left, right, edge); 122 pre->same_left_ptr->same_left_ptr = start; 123 if (set_of_vertex[right]->first_ptr == nullptr) 124 { 125 set_of_vertex[right]->first_ptr = pre->same_left_ptr; 126 return true; 127 } 128 pre = pre->same_left_ptr; 129 } 130 else 131 { 132 pre->same_right_ptr = new EdgeNode(left, right, edge); 133 pre->same_right_ptr->same_left_ptr = start; 134 if (set_of_vertex[right]->first_ptr == nullptr) 135 { 136 set_of_vertex[right]->first_ptr = pre->same_right_ptr; 137 return true; 138 } 139 pre = pre->same_right_ptr; 140 } 141 } 142 break; 143 } 144 } 145 if (start == nullptr) 146 { 147 if (pre->left == left) 148 { 149 if (pre->right == right) 150 return false; 151 pre->same_left_ptr = new EdgeNode(left, right, edge); 152 if (set_of_vertex[right]->first_ptr == nullptr) 153 { 154 set_of_vertex[right]->first_ptr = pre->same_left_ptr; 155 return true; 156 } 157 pre = pre->same_left_ptr; 158 } 159 else 160 { 161 if (pre->left == right) 162 return false; 163 pre->same_right_ptr = new EdgeNode(left, right, edge); 164 if (set_of_vertex[right]->first_ptr == nullptr) 165 { 166 set_of_vertex[right]->first_ptr = pre->same_right_ptr; 167 return true; 168 } 169 pre = pre->same_right_ptr; 170 } 171 } 172 } 173 174 if (pre == nullptr) 175 { 176 pre = set_of_vertex[left]->first_ptr; 177 } 178 179 EdgeNode *p = nullptr; 180 for (EdgeNode *start = set_of_vertex[right]->first_ptr; start != nullptr; ) 181 { 182 if ((start->right == right ? start->left : start->right) < left) 183 { 184 p = start; 185 if (start->right == right) 186 { 187 start = start->same_right_ptr; 188 } 189 else 190 { 191 start = start->same_left_ptr; 192 } 193 } 194 else 195 { 196 if (p == nullptr) 197 { 198 p = set_of_vertex[right]->first_ptr; 199 set_of_vertex[right]->first_ptr = pre; 200 pre->same_right_ptr = p; 201 } 202 else 203 { 204 if (p->right == right) 205 { 206 p->same_right_ptr = pre; 207 } 208 else 209 { 210 p->same_left_ptr = pre; 211 } 212 pre->same_right_ptr = start; 213 } 214 return true; 215 } 216 } 217 218 if (p->right == right) 219 { 220 p->same_right_ptr = pre; 221 } 222 else 223 { 224 p->same_left_ptr = pre; 225 } 226 return true; 227 } 228 229 template <typename V, typename E> 230 Graph<V, E>::~Graph() //刪除演算法較為簡潔,原因是和頂點關聯的所有邊另一端的頂點編號保持有序,這樣我們只需從小到大考察每個頂點,如果和頂點關聯的邊全部刪除,first_ptr指標為空,演算法會自動跳過,否則依次分離出和頂點關聯的每一條邊,從該邊關聯的非當前頂點的另一 231 { //頂點處對分離出的邊節點進行摘鏈(根據刪除演算法的執行順序,被摘鏈的邊節點一定是和另一頂點關聯的邊連結串列中的第一個節點),然後釋放分離出的邊節點,所有頂點處理完後銷燬set_of_vertex 232 for (typename vector<VertexNode *>::size_type run = 0; run < set_of_vertex.size(); ++run) 233 { 234 EdgeNode *ptr = nullptr; 235 while (set_of_vertex[run]->first_ptr != nullptr) 236 { 237 ptr = set_of_vertex[run]->first_ptr; 238 if (ptr->left == run) 239 { 240 set_of_vertex[run]->first_ptr = ptr->same_left_ptr; 241 set_of_vertex[ptr->right]->first_ptr = ptr->same_right_ptr; 242 } 243 else 244 { 245 set_of_vertex[run]->first_ptr = ptr->same_right_ptr; 246 set_of_vertex[ptr->left]->first_ptr = ptr->same_left_ptr; 247 } 248 delete ptr; 249 } 250 } 251 252 while (set_of_vertex.empty() == false) 253 { 254 delete set_of_vertex.back(); 255 set_of_vertex.pop_back(); 256 } 257 258 } 259 260 template <typename V, typename E> 261 Graph<V, E> *Graph<V, E>::copy() //依次考察原圖每一個頂點,對每一個頂點依次考察關聯的每一邊節點,如果該邊節點副本已在尚未拷貝完成的圖副本中,則將邊節點副本連結至圖副本對應頂點副本的邊連結串列的尾部,否則建立新節點(為當前邊節點副本)連結至圖副本對應頂點副本的邊連結串列的尾部 262 { //同時搜尋圖副本中已部分形成的通過和新邊節點關聯的另一端頂點(非原圖中當前遍歷到的頂點)對應的連結指標連結形成的邊連結串列的第一個邊節點,由該邊節點循鏈找到部分形成的邊連結串列尾部,將新節點連結至尾部即可 263 Graph<V, E> *temp = new Graph<V, E>(set_of_vertex.size()); 264 for (typename vector<VertexNode *>::size_type run = 0; run < set_of_vertex.size(); ++run) 265 { 266 temp->set_of_vertex[run] = new VertexNode(set_of_vertex[run]->number, new V(*(set_of_vertex[run]->vertex_data_field))); 267 if (set_of_vertex[run]->seilring != nullptr) 268 { 269 temp->set_of_vertex[run]->seilring = temp->set_of_vertex[run]; 270 temp->set_of_vertex[run]->Edgeseilring = new E(*(set_of_vertex[run]->Edgeseilring)); 271 } 272 273 if (set_of_vertex[run]->first_ptr == nullptr) 274 continue; 275 276 EdgeNode *p = nullptr; 277 for (EdgeNode *start = set_of_vertex[run]->first_ptr; start != nullptr; ) 278 { 279 if ((start->left == run ? start->right : start->left) < run) 280 { 281 EdgeNode *q = nullptr; 282 if (start->left == run) 283 { 284 q = temp->set_of_vertex[start->right]->first_ptr; 285 for (; q != nullptr; ) 286 { 287 if (q->left == start->right) 288 { 289 if (q->right == run) 290 break; 291 q = q->same_left_ptr; 292 } 293 else 294 { 295 if (q->left == run) 296 break; 297 q = q->same_right_ptr; 298 } 299 } 300 } 301 else 302 { 303 q = temp->set_of_vertex[start->left]->first_ptr; 304 for (; q != nullptr; ) 305 { 306 if (q->left == start->left) 307 { 308 if (q->right == run) 309 break; 310 q = q->same_left_ptr; 311 } 312 else 313 { 314 if (q->left == run) 315 break; 316 q = q->same_right_ptr; 317 } 318 } 319 } 320 321 if (p == nullptr) 322 { 323 p = temp->set_of_vertex[run]->first_ptr = q; 324 } 325 else 326 { 327 if (p->left == run) 328 { 329 p = p->same_left_ptr = q; 330 } 331 else 332 { 333 p = p->same_right_ptr = q; 334 } 335 } 336 } 337 else 338 { 339 if (p == nullptr) 340 { 341 p = temp->set_of_vertex[run]->first_ptr = new EdgeNode(start->left, start->right, new E(*(start->edge_data_field))); 342 } 343 else 344 { 345 if (p->left == run) 346 { 347 p = p->same_left_ptr = new EdgeNode(start->left, start->right, new E(*(start->edge_data_field))); 348 } 349 else 350 { 351 p = p->same_right_ptr = new EdgeNode(start->left, start->right, new E(*(start->edge_data_field))); 352 } 353 } 354 355 if (start->left == run) 356 { 357 EdgeNode *m = nullptr; 358 typename vector<VertexNode *>::size_type i = 0; 359 for ( ; i < run; ++i) 360 { 361 for (m = temp->set_of_vertex[i]->first_ptr; m != nullptr;) 362 { 363 if (m->left == i) 364 { 365 if (m->right == start->right) 366 break; 367 m = m->same_left_ptr; 368 } 369 else 370 { 371 if (m->left == start->right) 372 break; 373 m = m->same_right_ptr; 374 } 375 } 376 if (m != nullptr) 377 break; 378 } 379 380 if (i != run) 381 { 382 while (true) 383 { 384 if (m->right == start->right) 385 { 386 if (m->same_right_ptr == nullptr) 387 break; 388 m = m->same_right_ptr; 389 } 390 else 391 { 392 if (m->same_left_ptr == nullptr) 393 break; 394 m = m->same_left_ptr; 395 } 396 } 397 if (m->right == start->right) 398 { 399 m->same_right_ptr = p; 400 } 401 else 402 { 403 m->same_left_ptr = p; 404 } 405 } 406 } 407 else 408 { 409 EdgeNode *m = nullptr; 410 typename vector<VertexNode *>::size_type i = 0; 411 for (; i < run; ++i) 412 { 413 for (m = temp->set_of_vertex[i]->first_ptr; m != nullptr;) 414 { 415 if (m->left == i) 416 { 417 if (m->right == start->left) 418 break; 419 m = m->same_left_ptr; 420 } 421 else 422 { 423 if (m->left == start->left) 424 break; 425 m = m->same_right_ptr; 426 } 427 } 428 if (m != nullptr) 429 break; 430 } 431 432 if (i != run) 433 { 434 while (true) 435 { 436 if (m->right == start->left) 437 { 438 if (m->same_right_ptr == nullptr) 439 break; 440 m = m->same_right_ptr; 441 } 442 else 443 { 444 if (m->same_left_ptr == nullptr) 445 break; 446 m = m->same_left_ptr; 447 } 448 } 449 if (m->right == start->left) 450 { 451 m->same_right_ptr = p; 452 } 453 else 454 { 455 m->same_left_ptr = p; 456 } 457 } 458 } 459 } 460 461 if (start->left == run) 462 { 463 start = start->same_left_ptr; 464 } 465 else 466 { 467 start = start->same_right_ptr; 468 } 469 } 470 } 471 return temp; 472 } 473 474 template <typename V, typename E> 475 bool Graph<V, E>::deleteEdge(typename vector<VertexNode *>::size_type left, typename vector<VertexNode *>::size_type right) //從頂點left,right處搜尋邊節點,摘鏈並釋放邊節點 476 { 477 if (left >= set_of_vertex.size() || right >= set_of_vertex.size()) 478 { 479 throw new out_of_range("無效的頂點引數\\n"); 480 } 481 482 if (left == right) 483 { 484 set_of_vertex[left]->seilring = nullptr; 485 delete set_of_vertex[left]->Edgeseilring; 486 set_of_vertex[left]->Edgeseilring = nullptr; 487 return true; 488 } 489 490 if (set_of_vertex[left]->first_ptr == nullptr) 491 return false; 492 493 EdgeNode *q = nullptr; 494 EdgeNode *p = set_of_vertex[left]->first_ptr; 495 for (; p != nullptr; ) 496 { 497 if (p->left == left) 498 { 499 if (p->right == right) 500 { 501 break; 502 } 503 q = p; 504 p = p->same_left_ptr; 505 } 506 else 507 { 508 if (p->left == right) 509 { 510 break; 511 } 512 q = p; 513 p = p->same_right_ptr; 514 } 515 } 516 if (p == nullptr) 517 { 518 return false; 519 } 520 else 521 { 522 if (q == nullptr) 523 { 524 if (p->left == left) 525 { 526 set_of_vertex[left]->first_ptr = p->same_left_ptr; 527 } 528 else 529 { 530 set_of_vertex[left]->first_ptr = p->same_right_ptr; 531 } 532 } 533 else 534 { 535 if (q->left == left && p->left == left) 536 { 537 q->same_left_ptr = p->same_left_ptr; 538 } 539 else if (q->left != left) 540 { 541 if (p->left != left) 542 { 543 q->same_right_ptr = p->same_right_ptr; 544 } 545 else 546 { 547 q->same_right_ptr = p->same_left_ptr; 548 } 549 } 550 else 551 { 552 q->same_left_ptr = p->same_right_ptr; 553 } 554 } 555 } 556 557 EdgeNode *q2 = nullptr; 558 while (true) 559 { 560 if (q2 == nullptr) 561 { 562 if (set_of_vertex[right]->first_ptr->left == left || set_of_vertex[right]->first_ptr->right == left) 563 break; 564 q2 = set_of_vertex[right]->first_ptr; 565 continue; 566 } 567 else 568 { 569 if (q2->right == right) 570 { 571 if (q2->same_right_ptr->left == left || q2->same_right_ptr->right == left) 572 break; 573 q2 = q2->same_right_ptr; 574 } 575 else 576 { 577 if (q2->same_left_ptr->left == left || q2->same_left_ptr->right == left) 578 break; 579 q2 = q2->same_left_ptr; 580 } 581 } 582 } 583 584 if (q2 == nullptr) 585 { 586 if (p->left == left) 587 { 588 set_of_vertex[right]->first_ptr = p->same_right_ptr; 589 } 590 else 591 { 592 set_of_vertex[right]->first_ptr = p->same_left_ptr; 593 } 594 } 595 else 596 { 597 if (q2->left == right && p->left == left) 598 { 599 q2->same_left_ptr = p->same_left_ptr; 600 } 601 else if (q2->left != right) 602 { 603 if (p->left != left) 604 { 605 q2->same_right_ptr = p->same_right_ptr; 606 } 607 else 608 { 609 q2->same_right_ptr = p->same_left_ptr; 610 } 611 } 612 else 613 { 614 q2->same_left_ptr = p->same_right_ptr; 615 } 616 } 617 delete p; 618 } 619 620 template <typename V, typename E> 621 void Graph<V, E>::deleteVertex(typename vector<VertexNode *>::size_type vertex) //分離出和vertex關聯的每一邊節點,從該邊節點另一端頂點(和vertex相對應)出搜尋邊節點,摘鏈並釋放邊節點 622 { //隨後從set_of_vertex中刪去vertex並調整圖中頂點編號和邊節點中頂點編號 623 if (vertex >= set_of_vertex.size()) 624 { 625 throw new out_of_range("無效的頂點引數\\n"); 626 } 627 628 EdgeNode *ptr = nullptr; 629 while (set_of_vertex[vertex]->first_ptr != nullptr) 630 { 631 ptr = set_of_vertex[vertex]->first_ptr; 632 if (ptr->left == vertex) 633 { 634 set_of_vertex[vertex]->first_ptr = ptr->same_left_ptr; 635 EdgeNode *q2 = nullptr; 636 while (true) 637 { 638 if (q2 == nullptr) 639 { 640 if (set_of_vertex[ptr->right]->first_ptr->left == vertex || set_of_vertex[ptr->right]->first_ptr->right == vertex) 641 break; 642 q2 = set_of_vertex[ptr->right]->first_ptr; 643 continue; 644 } 645 else 646 { 647 if (q2->right == ptr->right) 648 { 649 if (q2->same_right_ptr->left == vertex || q2->same_right_ptr->right == vertex) 650 break; 651 q2 = q2->same_right_ptr; 652 } 653 else 654 { 655 if (q2->same_left_ptr->left == vertex || q2->same_left_ptr->right == vertex) 656 break; 657 q2 = q2->same_left_ptr; 658 } 659 } 660 } 661 662 if (q2 == nullptr) 663 { 664 set_of_vertex[ptr->right]->first_ptr = ptr->same_right_ptr; 665 } 666 else 667 { 668 if (q2->left == ptr->right) 669 { 670 q2->same_left_ptr = ptr->same_right_ptr; 671 } 672 else 673 { 674 q2->same_right_ptr = ptr->same_right_ptr; 675 } 676 } 677 } 678 else 679 { 680 set_of_vertex[vertex]->first_ptr = ptr->same_right_ptr; 681 EdgeNode *q2 = nullptr; 682 while (true) 683 { 684 if (q2 == nullptr) 685 { 686 if (set_of_vertex[ptr->left]->first_ptr->left == vertex || set_of_vertex[ptr->left]->first_ptr->right == vertex) 687 break; 688 q2 = set_of_vertex[ptr->left]->first_ptr; 689 continue; 690 } 691 else 692 { 693 if (q2->right == ptr->left) 694 { 695 if (q2->same_right_ptr->left == vertex || q2->same_right_ptr->right == vertex) 696 break; 697 q2 = q2->same_right_ptr; 698 } 699 else 700 { 701 if (q2->same_left_ptr->left == vertex || q2->same_left_ptr->right == vertex) 702 break; 703 q2 = q2->same_left_ptr; 704 } 705 } 706 } 707 708 if (q2 == nullptr) 709 { 710 set_of_vertex[ptr->left]->first_ptr = ptr->same_left_ptr; 711 } 712 else 713 { 714 if (q2->left != ptr->left) 715 { 716 q2->same_right_ptr = ptr->same_left_ptr; 717 } 718 else 719 { 720 q2->same_left_ptr = ptr->same_left_ptr; 721 } 722 } 723 } 724 delete ptr; 725 } 726 727 delete set_of_vertex[vertex]; 728 for (typename vector<VertexNode *>::size_type i = vertex; i < set_of_vertex.size() - 1; ++i) 729 { 730 set_of_vertex[i] = set_of_vertex[i + 1]; 731 --set_of_vertex[i]->number; 732 } 733 734 set_of_vertex.pop_back(); 735 set<EdgeNode *> visited; 736 for (typename vector<VertexNode *>::size_type i = 0; i < set_of_vertex.size(); ++i) 737 { 738 for (EdgeNode *q = set_of_vertex[i]->first_ptr; q != nullptr; ) 739 { 740 if (visited.find(q) == visited.end()) 741 { 742 if (q->left > vertex) 743 { 744 q->left = q->left - 1; 745 } 746 747 if (q->right > vertex) 748 { 749 q->right = q->right - 1; 750 } 751 visited.insert(q); 752 } 753 if (q->left == i) 754 { 755 q = q->same_left_ptr; 756 } 757 else 758 { 759 q = q->same_right_ptr; 760 } 761 } 762 } 763 } 764 765 template <typename V, typename E> 766 Graph<V, E> *Graph<V, E>::merge(Graph<V, E> &Bemerged, bool copyOrNot) //合併函式比較簡單,可以參考我在LALR(1)語法分析表生成程式中對十字連結串列的實現 767 { 768 Graph<V, E> *temp1 = nullptr; 769 typename vector<VertexNode *>::size_type Ca1 = 0; 770 if (copyOrNot) 771 { 772 temp1 = copy(); 773 Ca1 = temp1->set_of_vertex.size(); 774 } 775 else 776 { 777 Ca1 = set_of_vertex.size(); 778 } 779 780 { 781 Graph<V, E> *temp2 = Bemerged.copy(); 782 for (typename vector<VertexNode *>::size_type p = 0; p < temp2->set_of_vertex.size(); ++p) 783 { 784 if (copyOrNot) 785 { 786 temp1->set_of_vertex.push_back(temp2->set_of_vertex[p]); 787 } 788 else 789 { 790 set_of_vertex.push_back(temp2->set_of_vertex[p]); 791 } 792 } 793 while (temp2->set_of_vertex.empty() == false) 794 { 795 temp2->set_of_vertex.pop_back(); 796 } 797 delete temp2; 798 } 799 800 set<EdgeNode *> visited; 801 for (typename vector<VertexNode *>::size_type p = Ca1; ; ++p) 802 { 803 EdgeNode *q = nullptr; 804 if (copyOrNot) 805 { 806 if (p >= temp1->set_of_vertex.size()) 807 break; 808 temp1->set_of_vertex[p]->number = p; 809 q = temp1->set_of_vertex[p]->first_ptr; 810 } 811 else 812 { 813 if (p >= set_of_vertex.size()) 814 break; 815 set_of_vertex[p]->number = p; 816 q = set_of_vertex[p]->first_ptr; 817 } 818 819 for (; q != nullptr; ) 820 { 821 if (visited.find(q) == visited.end()) 822 { 823 q->left = q->left + Ca1; 824 q->right = q->right + Ca1; 825 visited.insert(q); 826 } 827 if (q->left == p) 828 { 829 q = q->same_left_ptr; 830 } 831 else 832 { 833 q = q->same_right_ptr; 834 } 835 } 836 } 837 838 if (copyOrNot) 839 return temp1; 840 else 841 return nullptr; 842 843 } 844 845 Graph<size_t, size_t> *convertToGraph(vector<vector<int>> &adjacency_matrix) //由鄰接矩陣構造基於鄰接多重表的有向圖並返回該圖的指標 846 { 847 vector<vector<int>>::size_type size = adjacency_matrix.size(); 848 Graph<size_t, size_t> *temp = new Graph<size_t, size_t>(); 849 for (size_t i = 0; i < size; ++i) 850 { 851 temp->addVertex(new size_t(i)); 852 } 853 for (size_t i = 0; i < size; ++i) 854 { 855 for (size_t j = i; j < size; ++j) 856 { 857 if (adjacency_matrix[i][j] == 1) 858 { 859 temp->addEdge(i, j, new size_t(j)); 860 } 861 } 862 } 863 return temp; 864 } 865 866 vector<vector<int>> *convertToAdjaMatrix(Graph<size_t, size_t> *undigraph) //由基於鄰接多重表無向圖構造鄰接矩陣並返回鄰接矩陣 867 { 868 vector<vector<int>> *temp = new vector<vector<int>>(undigraph->getVertexNum(), vector<int>(undigraph->getVertexNum(), 0)); 869 for (size_t i = 0; i < undigraph->set_of_vertex.size(); ++i) 870 { 871 if (undigraph->set_of_vertex[i]->seilring != nullptr) 872 (*temp)[i][i] = 1; 873 for (Graph<size_t, size_t>::EdgeNode *p = undigraph->set_of_vertex[i]->first_ptr; p != nullptr;) 874 { 875 if (p->left == i) 876 { 877 (*temp)[p->left][p->right] = 1; 878 p = p->same_left_ptr; 879 } 880 else 881 { 882 (*temp)[p->right][p->left] = 1; 883 p = p->same_right_ptr; 884 } 885 } 886 } 887 delete undigraph; 888 return temp; 889 } 890 891 int main() 892 { 893 vector<vector<int>> test = { {1, 0, 1, 1, 0, 1, 0}, {0, 1, 0, 1, 1, 0, 1}, {1, 0, 0, 0, 1, 1, 1}, {1, 1, 0, 1, 1, 0, 0}, {0, 1, 1, 1, 0, 1, 1}, {1, 0,