Changeset 209:765619b7cbb2 in lemon for lemon/unionfind.h
- Timestamp:
- 07/13/08 20:51:02 (17 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/unionfind.h
r103 r209 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 5 * Copyright (C) 2003-2008 … … 39 39 /// \brief A \e Union-Find data structure implementation 40 40 /// 41 /// The class implements the \e Union-Find data structure. 41 /// The class implements the \e Union-Find data structure. 42 42 /// The union operation uses rank heuristic, while 43 43 /// the find operation uses path compression. 44 /// This is a very simple but efficient implementation, providing 44 /// This is a very simple but efficient implementation, providing 45 45 /// only four methods: join (union), find, insert and size. 46 46 /// For more features see the \ref UnionFindEnum class. … … 51 51 /// 52 52 /// \pre You need to add all the elements by the \ref insert() 53 /// method. 53 /// method. 54 54 template <typename _ItemIntMap> 55 55 class UnionFind { … … 112 112 /// \brief Inserts a new element into the structure. 113 113 /// 114 /// This method inserts a new element into the data structure. 114 /// This method inserts a new element into the data structure. 115 115 /// 116 116 /// The method returns the index of the new component. … … 124 124 /// \brief Joining the components of element \e a and element \e b. 125 125 /// 126 /// This is the \e union operation of the Union-Find structure. 126 /// This is the \e union operation of the Union-Find structure. 127 127 /// Joins the component of element \e a and component of 128 128 /// element \e b. If \e a and \e b are in the same component then … … 132 132 int kb = repIndex(index[b]); 133 133 134 if ( ka == kb ) 135 134 if ( ka == kb ) 135 return false; 136 136 137 137 if (items[ka] < items[kb]) { 138 139 138 items[ka] += items[kb]; 139 items[kb] = ka; 140 140 } else { 141 142 141 items[kb] += items[ka]; 142 items[ka] = kb; 143 143 } 144 144 return true; … … 174 174 class UnionFindEnum { 175 175 public: 176 176 177 177 typedef _ItemIntMap ItemIntMap; 178 178 typedef typename ItemIntMap::Key Item; 179 179 180 180 private: 181 181 182 182 ItemIntMap& index; 183 183 … … 203 203 int next, prev; 204 204 }; 205 205 206 206 std::vector<ClassT> classes; 207 207 int firstClass, firstFreeClass; … … 209 209 int newClass() { 210 210 if (firstFreeClass == -1) { 211 212 213 211 int cdx = classes.size(); 212 classes.push_back(ClassT()); 213 return cdx; 214 214 } else { 215 216 217 215 int cdx = firstFreeClass; 216 firstFreeClass = classes[firstFreeClass].next; 217 return cdx; 218 218 } 219 219 } … … 221 221 int newItem() { 222 222 if (firstFreeItem == -1) { 223 224 225 223 int idx = items.size(); 224 items.push_back(ItemT()); 225 return idx; 226 226 } else { 227 228 229 227 int idx = firstFreeItem; 228 firstFreeItem = items[firstFreeItem].next; 229 return idx; 230 230 } 231 231 } … … 268 268 items[items[idx].prev].next = items[idx].next; 269 269 items[items[idx].next].prev = items[idx].prev; 270 270 271 271 items[idx].next = firstFreeItem; 272 272 firstFreeItem = idx; … … 279 279 items[ak].prev = items[bk].prev; 280 280 items[bk].prev = tmp; 281 281 282 282 } 283 283 … … 289 289 classes[cls].prev = -1; 290 290 firstClass = cls; 291 } 291 } 292 292 293 293 void unlaceClass(int cls) { … … 300 300 classes[classes[cls].next].prev = classes[cls].prev; 301 301 } 302 302 303 303 classes[cls].next = firstFreeClass; 304 304 firstFreeClass = cls; 305 } 305 } 306 306 307 307 public: 308 308 309 UnionFindEnum(ItemIntMap& _index) 310 : index(_index), items(), firstFreeItem(-1), 311 312 309 UnionFindEnum(ItemIntMap& _index) 310 : index(_index), items(), firstFreeItem(-1), 311 firstClass(-1), firstFreeClass(-1) {} 312 313 313 /// \brief Inserts the given element into a new component. 314 314 /// … … 333 333 334 334 firstClass = cdx; 335 335 336 336 return cdx; 337 337 } … … 340 340 /// 341 341 /// This methods inserts the element \e a into the component of the 342 /// element \e comp. 342 /// element \e comp. 343 343 void insert(const Item& item, int cls) { 344 344 int rdx = classes[cls].firstItem; … … 373 373 /// \brief Joining the component of element \e a and element \e b. 374 374 /// 375 /// This is the \e union operation of the Union-Find structure. 375 /// This is the \e union operation of the Union-Find structure. 376 376 /// Joins the component of element \e a and component of 377 377 /// element \e b. If \e a and \e b are in the same component then … … 383 383 384 384 if (ak == bk) { 385 385 return -1; 386 386 } 387 387 … … 392 392 393 393 if (classes[acx].size > classes[bcx].size) { 394 395 394 classes[acx].size += classes[bcx].size; 395 items[bk].parent = ak; 396 396 unlaceClass(bcx); 397 397 rcx = acx; 398 398 } else { 399 400 399 classes[bcx].size += classes[acx].size; 400 items[ak].parent = bk; 401 401 unlaceClass(acx); 402 402 rcx = bcx; 403 403 } 404 404 spliceItems(ak, bk); … … 414 414 } 415 415 416 /// \brief Splits up the component. 416 /// \brief Splits up the component. 417 417 /// 418 418 /// Splitting the component into singleton components (component … … 424 424 int next = items[idx].next; 425 425 426 427 428 int cdx = newClass(); 426 singletonItem(idx); 427 428 int cdx = newClass(); 429 429 items[idx].parent = ~cdx; 430 430 431 432 433 434 431 laceClass(cdx); 432 classes[cdx].size = 1; 433 classes[cdx].firstItem = idx; 434 435 435 idx = next; 436 436 } … … 440 440 441 441 classes[~(items[idx].parent)].size = 1; 442 442 443 443 } 444 444 … … 458 458 int cdx = classIndex(idx); 459 459 if (idx == fdx) { 460 461 462 463 460 unlaceClass(cdx); 461 items[idx].next = firstFreeItem; 462 firstFreeItem = idx; 463 return; 464 464 } else { 465 466 467 468 469 470 471 472 473 474 475 465 classes[cdx].firstItem = fdx; 466 --classes[cdx].size; 467 items[fdx].parent = ~cdx; 468 469 unlaceItem(idx); 470 idx = items[fdx].next; 471 while (idx != fdx) { 472 items[idx].parent = fdx; 473 idx = items[idx].next; 474 } 475 476 476 } 477 477 … … 515 515 /// Constructor to get invalid iterator 516 516 ClassIt(Invalid) : unionFind(0), cdx(-1) {} 517 517 518 518 /// \brief Increment operator 519 519 /// … … 523 523 return *this; 524 524 } 525 525 526 526 /// \brief Conversion operator 527 527 /// … … 534 534 /// 535 535 /// Equality operator 536 bool operator==(const ClassIt& i) { 536 bool operator==(const ClassIt& i) { 537 537 return i.cdx == cdx; 538 538 } … … 541 541 /// 542 542 /// Inequality operator 543 bool operator!=(const ClassIt& i) { 543 bool operator!=(const ClassIt& i) { 544 544 return i.cdx != cdx; 545 545 } 546 546 547 547 private: 548 548 const UnionFindEnum* unionFind; … … 578 578 /// Constructor to get invalid iterator 579 579 ItemIt(Invalid) : unionFind(0), idx(-1) {} 580 580 581 581 /// \brief Increment operator 582 582 /// … … 587 587 return *this; 588 588 } 589 589 590 590 /// \brief Conversion operator 591 591 /// … … 598 598 /// 599 599 /// Equality operator 600 bool operator==(const ItemIt& i) { 600 bool operator==(const ItemIt& i) { 601 601 return i.idx == idx; 602 602 } … … 605 605 /// 606 606 /// Inequality operator 607 bool operator!=(const ItemIt& i) { 607 bool operator!=(const ItemIt& i) { 608 608 return i.idx != idx; 609 609 } 610 610 611 611 private: 612 612 const UnionFindEnum* unionFind; … … 631 631 class ExtendFindEnum { 632 632 public: 633 633 634 634 typedef _ItemIntMap ItemIntMap; 635 635 typedef typename ItemIntMap::Key Item; 636 636 637 637 private: 638 638 639 639 ItemIntMap& index; 640 640 … … 659 659 int newClass() { 660 660 if (firstFreeClass != -1) { 661 662 663 661 int cdx = firstFreeClass; 662 firstFreeClass = classes[cdx].next; 663 return cdx; 664 664 } else { 665 666 665 classes.push_back(ClassT()); 666 return classes.size() - 1; 667 667 } 668 668 } … … 670 670 int newItem() { 671 671 if (firstFreeItem != -1) { 672 673 674 672 int idx = firstFreeItem; 673 firstFreeItem = items[idx].next; 674 return idx; 675 675 } else { 676 677 676 items.push_back(ItemT()); 677 return items.size() - 1; 678 678 } 679 679 } … … 682 682 683 683 /// \brief Constructor 684 ExtendFindEnum(ItemIntMap& _index) 685 : index(_index), items(), firstFreeItem(-1), 686 687 684 ExtendFindEnum(ItemIntMap& _index) 685 : index(_index), items(), firstFreeItem(-1), 686 classes(), firstClass(-1), firstFreeClass(-1) {} 687 688 688 /// \brief Inserts the given element into a new component. 689 689 /// … … 695 695 classes[cdx].next = firstClass; 696 696 if (firstClass != -1) { 697 697 classes[firstClass].prev = cdx; 698 698 } 699 699 firstClass = cdx; 700 700 701 701 int idx = newItem(); 702 702 items[idx].item = item; … … 708 708 709 709 index.set(item, idx); 710 710 711 711 return cdx; 712 712 } … … 751 751 return items[classes[cls].firstItem].item; 752 752 } 753 753 754 754 /// \brief Removes the given element from the structure. 755 755 /// … … 762 762 int idx = index[item]; 763 763 int cdx = items[idx].cls; 764 764 765 765 if (idx == items[idx].next) { 766 767 classes[classes[cdx].prev].next = classes[cdx].next; 768 769 770 771 772 classes[classes[cdx].next].prev = classes[cdx].prev; 773 774 775 766 if (classes[cdx].prev != -1) { 767 classes[classes[cdx].prev].next = classes[cdx].next; 768 } else { 769 firstClass = classes[cdx].next; 770 } 771 if (classes[cdx].next != -1) { 772 classes[classes[cdx].next].prev = classes[cdx].prev; 773 } 774 classes[cdx].next = firstFreeClass; 775 firstFreeClass = cdx; 776 776 } else { 777 778 779 777 classes[cdx].firstItem = items[idx].next; 778 items[items[idx].next].prev = items[idx].prev; 779 items[items[idx].prev].next = items[idx].next; 780 780 } 781 781 items[idx].next = firstFreeItem; 782 782 firstFreeItem = idx; 783 784 } 785 786 783 784 } 785 786 787 787 /// \brief Removes the component of the given element from the structure. 788 788 /// … … 797 797 798 798 if (classes[cdx].prev != -1) { 799 classes[classes[cdx].prev].next = classes[cdx].next; 799 classes[classes[cdx].prev].next = classes[cdx].next; 800 800 } else { 801 801 firstClass = classes[cdx].next; 802 802 } 803 803 if (classes[cdx].next != -1) { 804 classes[classes[cdx].next].prev = classes[cdx].prev; 804 classes[classes[cdx].next].prev = classes[cdx].prev; 805 805 } 806 806 classes[cdx].next = firstFreeClass; … … 825 825 /// Constructor to get invalid iterator 826 826 ClassIt(Invalid) : extendFind(0), cdx(-1) {} 827 827 828 828 /// \brief Increment operator 829 829 /// … … 833 833 return *this; 834 834 } 835 835 836 836 /// \brief Conversion operator 837 837 /// … … 844 844 /// 845 845 /// Equality operator 846 bool operator==(const ClassIt& i) { 846 bool operator==(const ClassIt& i) { 847 847 return i.cdx == cdx; 848 848 } … … 851 851 /// 852 852 /// Inequality operator 853 bool operator!=(const ClassIt& i) { 853 bool operator!=(const ClassIt& i) { 854 854 return i.cdx != cdx; 855 855 } 856 856 857 857 private: 858 858 const ExtendFindEnum* extendFind; … … 888 888 /// Constructor to get invalid iterator 889 889 ItemIt(Invalid) : extendFind(0), idx(-1) {} 890 890 891 891 /// \brief Increment operator 892 892 /// … … 894 894 ItemIt& operator++() { 895 895 idx = extendFind->items[idx].next; 896 896 if (fdx == idx) idx = -1; 897 897 return *this; 898 898 } 899 899 900 900 /// \brief Conversion operator 901 901 /// … … 908 908 /// 909 909 /// Equality operator 910 bool operator==(const ItemIt& i) { 910 bool operator==(const ItemIt& i) { 911 911 return i.idx == idx; 912 912 } … … 915 915 /// 916 916 /// Inequality operator 917 bool operator!=(const ItemIt& i) { 917 bool operator!=(const ItemIt& i) { 918 918 return i.idx != idx; 919 919 } 920 920 921 921 private: 922 922 const ExtendFindEnum* extendFind; … … 950 950 /// method. 951 951 /// 952 template <typename _Value, typename _ItemIntMap, 952 template <typename _Value, typename _ItemIntMap, 953 953 typename _Comp = std::less<_Value> > 954 954 class HeapUnionFind { 955 955 public: 956 956 957 957 typedef _Value Value; 958 958 typedef typename _ItemIntMap::Key Item; … … 1055 1055 id = nodes[id].next; 1056 1056 while (depth--) { 1057 id = nodes[id].left; 1057 id = nodes[id].left; 1058 1058 } 1059 1059 return id; … … 1133 1133 nodes[kd].right = nodes[id].prev; 1134 1134 nodes[nodes[id].prev].next = -1; 1135 1135 1136 1136 nodes[jd].left = id; 1137 1137 nodes[id].prev = -1; … … 1142 1142 id = nodes[id].next; 1143 1143 ++num; 1144 } 1144 } 1145 1145 nodes[kd].size -= num; 1146 1146 nodes[jd].size = num; … … 1166 1166 int jd = ~(classes[id].parent); 1167 1167 while (nodes[jd].left != -1) { 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 } 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 } 1205 } 1168 int kd = nodes[jd].left; 1169 if (nodes[jd].size == 1) { 1170 if (nodes[jd].parent < 0) { 1171 classes[id].parent = ~kd; 1172 classes[id].depth -= 1; 1173 nodes[kd].parent = ~id; 1174 deleteNode(jd); 1175 jd = kd; 1176 } else { 1177 int pd = nodes[jd].parent; 1178 if (nodes[nodes[jd].next].size < cmax) { 1179 pushLeft(nodes[jd].next, nodes[jd].left); 1180 if (less(nodes[jd].left, nodes[jd].next)) { 1181 nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio; 1182 nodes[nodes[jd].next].item = nodes[nodes[jd].left].item; 1183 } 1184 popLeft(pd); 1185 deleteNode(jd); 1186 jd = pd; 1187 } else { 1188 int ld = nodes[nodes[jd].next].left; 1189 popLeft(nodes[jd].next); 1190 pushRight(jd, ld); 1191 if (less(ld, nodes[jd].left)) { 1192 nodes[jd].item = nodes[ld].item; 1193 nodes[jd].prio = nodes[jd].prio; 1194 } 1195 if (nodes[nodes[jd].next].item == nodes[ld].item) { 1196 setPrio(nodes[jd].next); 1197 } 1198 jd = nodes[jd].left; 1199 } 1200 } 1201 } else { 1202 jd = nodes[jd].left; 1203 } 1204 } 1205 } 1206 1206 1207 1207 void repairRight(int id) { 1208 1208 int jd = ~(classes[id].parent); 1209 1209 while (nodes[jd].right != -1) { 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 } 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1210 int kd = nodes[jd].right; 1211 if (nodes[jd].size == 1) { 1212 if (nodes[jd].parent < 0) { 1213 classes[id].parent = ~kd; 1214 classes[id].depth -= 1; 1215 nodes[kd].parent = ~id; 1216 deleteNode(jd); 1217 jd = kd; 1218 } else { 1219 int pd = nodes[jd].parent; 1220 if (nodes[nodes[jd].prev].size < cmax) { 1221 pushRight(nodes[jd].prev, nodes[jd].right); 1222 if (less(nodes[jd].right, nodes[jd].prev)) { 1223 nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio; 1224 nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item; 1225 } 1226 popRight(pd); 1227 deleteNode(jd); 1228 jd = pd; 1229 } else { 1230 int ld = nodes[nodes[jd].prev].right; 1231 popRight(nodes[jd].prev); 1232 pushLeft(jd, ld); 1233 if (less(ld, nodes[jd].right)) { 1234 nodes[jd].item = nodes[ld].item; 1235 nodes[jd].prio = nodes[jd].prio; 1236 } 1237 if (nodes[nodes[jd].prev].item == nodes[ld].item) { 1238 setPrio(nodes[jd].prev); 1239 } 1240 jd = nodes[jd].right; 1241 } 1242 } 1243 } else { 1244 jd = nodes[jd].right; 1245 } 1246 1246 } 1247 1247 } … … 1277 1277 /// \brief Constructs the union-find. 1278 1278 /// 1279 /// Constructs the union-find. 1279 /// Constructs the union-find. 1280 1280 /// \brief _index The index map of the union-find. The data 1281 1281 /// structure uses internally for store references. 1282 HeapUnionFind(ItemIntMap& _index) 1283 : index(_index), first_class(-1), 1284 1282 HeapUnionFind(ItemIntMap& _index) 1283 : index(_index), first_class(-1), 1284 first_free_class(-1), first_free_node(-1) {} 1285 1285 1286 1286 /// \brief Insert a new node into a new component. … … 1304 1304 nodes[id].item = item; 1305 1305 index[item] = id; 1306 1306 1307 1307 int class_id = newClass(); 1308 1308 classes[class_id].parent = ~id; … … 1311 1311 classes[class_id].left = -1; 1312 1312 classes[class_id].right = -1; 1313 1313 1314 1314 if (first_class != -1) { 1315 1315 classes[first_class].prev = class_id; … … 1320 1320 1321 1321 nodes[id].parent = ~class_id; 1322 1322 1323 1323 return class_id; 1324 1324 } … … 1333 1333 return findClass(index[item]); 1334 1334 } 1335 1335 1336 1336 /// \brief Joins the classes. 1337 1337 /// … … 1372 1372 } 1373 1373 classes[classes[l].prev].next = classes[l].next; 1374 1374 1375 1375 classes[l].prev = -1; 1376 1376 classes[l].next = -1; … … 1378 1378 classes[l].depth = leftNode(l); 1379 1379 classes[l].parent = class_id; 1380 1380 1381 1381 } 1382 1382 … … 1456 1456 pushLeft(new_parent, ~(classes[l].parent)); 1457 1457 setPrio(new_parent); 1458 1458 1459 1459 classes[r].parent = ~new_parent; 1460 1460 classes[r].depth += 1; … … 1471 1471 classes[l].depth = classes[r].depth; 1472 1472 } else { 1473 if (classes[l].depth != 0 && 1474 nodes[~(classes[l].parent)].size + 1473 if (classes[l].depth != 0 && 1474 nodes[~(classes[l].parent)].size + 1475 1475 nodes[~(classes[r].parent)].size <= cmax) { 1476 1476 splice(~(classes[l].parent), ~(classes[r].parent)); 1477 1477 deleteNode(~(classes[r].parent)); 1478 1478 if (less(~(classes[r].parent), ~(classes[l].parent))) { 1479 nodes[~(classes[l].parent)].prio = 1479 nodes[~(classes[l].parent)].prio = 1480 1480 nodes[~(classes[r].parent)].prio; 1481 nodes[~(classes[l].parent)].item = 1481 nodes[~(classes[l].parent)].item = 1482 1482 nodes[~(classes[r].parent)].item; 1483 1483 } … … 1488 1488 pushRight(new_parent, ~(classes[r].parent)); 1489 1489 setPrio(new_parent); 1490 1490 1491 1491 classes[l].parent = ~new_parent; 1492 1492 classes[l].depth += 1; … … 1543 1543 classes[first_class].prev = classes[id].right; 1544 1544 first_class = classes[id].left; 1545 1545 1546 1546 if (classes[id].next != -1) { 1547 1547 classes[classes[id].next].prev = classes[id].prev; 1548 1548 } 1549 1549 classes[classes[id].prev].next = classes[id].next; 1550 1550 1551 1551 deleteClass(id); 1552 1552 } … … 1558 1558 l = nodes[l].parent; 1559 1559 } 1560 int r = l; 1560 int r = l; 1561 1561 while (nodes[l].parent >= 0) { 1562 1562 l = nodes[l].parent; … … 1581 1581 repairRight(~(nodes[l].parent)); 1582 1582 repairLeft(cs[i]); 1583 1583 1584 1584 *out++ = cs[i]; 1585 1585 } … … 1604 1604 } 1605 1605 } 1606 1606 1607 1607 /// \brief Increase the priority of the current item. 1608 1608 /// … … 1631 1631 } 1632 1632 } 1633 1633 1634 1634 /// \brief Gives back the minimum priority of the class. 1635 1635 /// … … 1647 1647 1648 1648 /// \brief Gives back a representant item of the class. 1649 /// 1649 /// 1650 1650 /// The representant is indpendent from the priorities of the 1651 /// items. 1651 /// items. 1652 1652 /// \return Gives back a representant item of the class. 1653 1653 const Item& classRep(int id) const { … … 1675 1675 const HeapUnionFind* _huf; 1676 1676 int _id, _lid; 1677 1677 1678 1678 public: 1679 1679 1680 /// \brief Default constructor 1681 /// 1682 /// Default constructor 1680 /// \brief Default constructor 1681 /// 1682 /// Default constructor 1683 1683 ItemIt() {} 1684 1684 … … 1696 1696 _id = _huf->leftNode(id); 1697 1697 _lid = -1; 1698 } 1699 } 1700 1698 } 1699 } 1700 1701 1701 /// \brief Increment operator 1702 1702 /// … … 1713 1713 return _huf->nodes[_id].item; 1714 1714 } 1715 1715 1716 1716 /// \brief Equality operator 1717 1717 /// 1718 1718 /// Equality operator 1719 bool operator==(const ItemIt& i) { 1719 bool operator==(const ItemIt& i) { 1720 1720 return i._id == _id; 1721 1721 } … … 1724 1724 /// 1725 1725 /// Inequality operator 1726 bool operator!=(const ItemIt& i) { 1726 bool operator!=(const ItemIt& i) { 1727 1727 return i._id != _id; 1728 1728 } … … 1731 1731 /// 1732 1732 /// Equality operator 1733 bool operator==(Invalid) { 1733 bool operator==(Invalid) { 1734 1734 return _id == _lid; 1735 1735 } … … 1738 1738 /// 1739 1739 /// Inequality operator 1740 bool operator!=(Invalid) { 1740 bool operator!=(Invalid) { 1741 1741 return _id != _lid; 1742 1742 } 1743 1743 1744 1744 }; 1745 1745 1746 1746 /// \brief Class iterator 1747 1747 /// 1748 /// The iterator stores 1748 /// The iterator stores 1749 1749 class ClassIt { 1750 1750 private: … … 1755 1755 public: 1756 1756 1757 ClassIt(const HeapUnionFind& huf) 1757 ClassIt(const HeapUnionFind& huf) 1758 1758 : _huf(&huf), _id(huf.first_class) {} 1759 1759 1760 ClassIt(const HeapUnionFind& huf, int cls) 1760 ClassIt(const HeapUnionFind& huf, int cls) 1761 1761 : _huf(&huf), _id(huf.classes[cls].left) {} 1762 1762 1763 1763 ClassIt(Invalid) : _huf(0), _id(-1) {} 1764 1764 1765 1765 const ClassIt& operator++() { 1766 1766 _id = _huf->classes[_id].next; 1767 1767 return *this; 1768 1768 } 1769 1769 … … 1771 1771 /// 1772 1772 /// Equality operator 1773 bool operator==(const ClassIt& i) { 1773 bool operator==(const ClassIt& i) { 1774 1774 return i._id == _id; 1775 1775 } … … 1778 1778 /// 1779 1779 /// Inequality operator 1780 bool operator!=(const ClassIt& i) { 1780 bool operator!=(const ClassIt& i) { 1781 1781 return i._id != _id; 1782 } 1783 1782 } 1783 1784 1784 operator int() const { 1785 1786 } 1787 1785 return _id; 1786 } 1787 1788 1788 }; 1789 1789
Note: See TracChangeset
for help on using the changeset viewer.