gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix clear() function in ExtendFindEnum (#335)
0 1 0
default
1 file changed with 1 insertions and 1 deletions:
↑ Collapse diff ↑
Show white space 512 line context
... ...
@@ -486,513 +486,513 @@
486 486
    /// Gives back a representant item of the component.
487 487
    Item item(int cls) const {
488 488
      return items[classes[cls].firstItem].item;
489 489
    }
490 490

	
491 491
    /// \brief Removes the component of the given element from the structure.
492 492
    ///
493 493
    /// Removes the component of the given element from the structure.
494 494
    ///
495 495
    /// \warning It is an error to give an element which is not in the
496 496
    /// structure.
497 497
    void eraseClass(int cls) {
498 498
      int fdx = classes[cls].firstItem;
499 499
      unlaceClass(cls);
500 500
      items[items[fdx].prev].next = firstFreeItem;
501 501
      firstFreeItem = fdx;
502 502
    }
503 503

	
504 504
    /// \brief LEMON style iterator for the representant items.
505 505
    ///
506 506
    /// ClassIt is a lemon style iterator for the components. It iterates
507 507
    /// on the ids of the classes.
508 508
    class ClassIt {
509 509
    public:
510 510
      /// \brief Constructor of the iterator
511 511
      ///
512 512
      /// Constructor of the iterator
513 513
      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
514 514
        cdx = unionFind->firstClass;
515 515
      }
516 516

	
517 517
      /// \brief Constructor to get invalid iterator
518 518
      ///
519 519
      /// Constructor to get invalid iterator
520 520
      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
521 521

	
522 522
      /// \brief Increment operator
523 523
      ///
524 524
      /// It steps to the next representant item.
525 525
      ClassIt& operator++() {
526 526
        cdx = unionFind->classes[cdx].next;
527 527
        return *this;
528 528
      }
529 529

	
530 530
      /// \brief Conversion operator
531 531
      ///
532 532
      /// It converts the iterator to the current representant item.
533 533
      operator int() const {
534 534
        return cdx;
535 535
      }
536 536

	
537 537
      /// \brief Equality operator
538 538
      ///
539 539
      /// Equality operator
540 540
      bool operator==(const ClassIt& i) {
541 541
        return i.cdx == cdx;
542 542
      }
543 543

	
544 544
      /// \brief Inequality operator
545 545
      ///
546 546
      /// Inequality operator
547 547
      bool operator!=(const ClassIt& i) {
548 548
        return i.cdx != cdx;
549 549
      }
550 550

	
551 551
    private:
552 552
      const UnionFindEnum* unionFind;
553 553
      int cdx;
554 554
    };
555 555

	
556 556
    /// \brief LEMON style iterator for the items of a component.
557 557
    ///
558 558
    /// ClassIt is a lemon style iterator for the components. It iterates
559 559
    /// on the items of a class. By example if you want to iterate on
560 560
    /// each items of each classes then you may write the next code.
561 561
    ///\code
562 562
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
563 563
    ///   std::cout << "Class: ";
564 564
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
565 565
    ///     std::cout << toString(iit) << ' ' << std::endl;
566 566
    ///   }
567 567
    ///   std::cout << std::endl;
568 568
    /// }
569 569
    ///\endcode
570 570
    class ItemIt {
571 571
    public:
572 572
      /// \brief Constructor of the iterator
573 573
      ///
574 574
      /// Constructor of the iterator. The iterator iterates
575 575
      /// on the class of the \c item.
576 576
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
577 577
        fdx = idx = unionFind->classes[cls].firstItem;
578 578
      }
579 579

	
580 580
      /// \brief Constructor to get invalid iterator
581 581
      ///
582 582
      /// Constructor to get invalid iterator
583 583
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
584 584

	
585 585
      /// \brief Increment operator
586 586
      ///
587 587
      /// It steps to the next item in the class.
588 588
      ItemIt& operator++() {
589 589
        idx = unionFind->items[idx].next;
590 590
        if (idx == fdx) idx = -1;
591 591
        return *this;
592 592
      }
593 593

	
594 594
      /// \brief Conversion operator
595 595
      ///
596 596
      /// It converts the iterator to the current item.
597 597
      operator const Item&() const {
598 598
        return unionFind->items[idx].item;
599 599
      }
600 600

	
601 601
      /// \brief Equality operator
602 602
      ///
603 603
      /// Equality operator
604 604
      bool operator==(const ItemIt& i) {
605 605
        return i.idx == idx;
606 606
      }
607 607

	
608 608
      /// \brief Inequality operator
609 609
      ///
610 610
      /// Inequality operator
611 611
      bool operator!=(const ItemIt& i) {
612 612
        return i.idx != idx;
613 613
      }
614 614

	
615 615
    private:
616 616
      const UnionFindEnum* unionFind;
617 617
      int idx, fdx;
618 618
    };
619 619

	
620 620
  };
621 621

	
622 622
  /// \ingroup auxdat
623 623
  ///
624 624
  /// \brief A \e Extend-Find data structure implementation which
625 625
  /// is able to enumerate the components.
626 626
  ///
627 627
  /// The class implements an \e Extend-Find data structure which is
628 628
  /// able to enumerate the components and the items in a
629 629
  /// component. The data structure is a simplification of the
630 630
  /// Union-Find structure, and it does not allow to merge two components.
631 631
  ///
632 632
  /// \pre You need to add all the elements by the \ref insert()
633 633
  /// method.
634 634
  template <typename IM>
635 635
  class ExtendFindEnum {
636 636
  public:
637 637

	
638 638
    ///\e
639 639
    typedef IM ItemIntMap;
640 640
    ///\e
641 641
    typedef typename ItemIntMap::Key Item;
642 642

	
643 643
  private:
644 644

	
645 645
    ItemIntMap& index;
646 646

	
647 647
    struct ItemT {
648 648
      int cls;
649 649
      Item item;
650 650
      int next, prev;
651 651
    };
652 652

	
653 653
    std::vector<ItemT> items;
654 654
    int firstFreeItem;
655 655

	
656 656
    struct ClassT {
657 657
      int firstItem;
658 658
      int next, prev;
659 659
    };
660 660

	
661 661
    std::vector<ClassT> classes;
662 662

	
663 663
    int firstClass, firstFreeClass;
664 664

	
665 665
    int newClass() {
666 666
      if (firstFreeClass != -1) {
667 667
        int cdx = firstFreeClass;
668 668
        firstFreeClass = classes[cdx].next;
669 669
        return cdx;
670 670
      } else {
671 671
        classes.push_back(ClassT());
672 672
        return classes.size() - 1;
673 673
      }
674 674
    }
675 675

	
676 676
    int newItem() {
677 677
      if (firstFreeItem != -1) {
678 678
        int idx = firstFreeItem;
679 679
        firstFreeItem = items[idx].next;
680 680
        return idx;
681 681
      } else {
682 682
        items.push_back(ItemT());
683 683
        return items.size() - 1;
684 684
      }
685 685
    }
686 686

	
687 687
  public:
688 688

	
689 689
    /// \brief Constructor
690 690
    ExtendFindEnum(ItemIntMap& _index)
691 691
      : index(_index), items(), firstFreeItem(-1),
692 692
        classes(), firstClass(-1), firstFreeClass(-1) {}
693 693

	
694 694
    /// \brief Inserts the given element into a new component.
695 695
    ///
696 696
    /// This method creates a new component consisting only of the
697 697
    /// given element.
698 698
    int insert(const Item& item) {
699 699
      int cdx = newClass();
700 700
      classes[cdx].prev = -1;
701 701
      classes[cdx].next = firstClass;
702 702
      if (firstClass != -1) {
703 703
        classes[firstClass].prev = cdx;
704 704
      }
705 705
      firstClass = cdx;
706 706

	
707 707
      int idx = newItem();
708 708
      items[idx].item = item;
709 709
      items[idx].cls = cdx;
710 710
      items[idx].prev = idx;
711 711
      items[idx].next = idx;
712 712

	
713 713
      classes[cdx].firstItem = idx;
714 714

	
715 715
      index.set(item, idx);
716 716

	
717 717
      return cdx;
718 718
    }
719 719

	
720 720
    /// \brief Inserts the given element into the given component.
721 721
    ///
722 722
    /// This methods inserts the element \e item a into the \e cls class.
723 723
    void insert(const Item& item, int cls) {
724 724
      int idx = newItem();
725 725
      int rdx = classes[cls].firstItem;
726 726
      items[idx].item = item;
727 727
      items[idx].cls = cls;
728 728

	
729 729
      items[idx].prev = rdx;
730 730
      items[idx].next = items[rdx].next;
731 731
      items[items[rdx].next].prev = idx;
732 732
      items[rdx].next = idx;
733 733

	
734 734
      index.set(item, idx);
735 735
    }
736 736

	
737 737
    /// \brief Clears the union-find data structure
738 738
    ///
739 739
    /// Erase each item from the data structure.
740 740
    void clear() {
741 741
      items.clear();
742
      classes.clear;
742
      classes.clear();
743 743
      firstClass = firstFreeClass = firstFreeItem = -1;
744 744
    }
745 745

	
746 746
    /// \brief Gives back the class of the \e item.
747 747
    ///
748 748
    /// Gives back the class of the \e item.
749 749
    int find(const Item &item) const {
750 750
      return items[index[item]].cls;
751 751
    }
752 752

	
753 753
    /// \brief Gives back a representant item of the component.
754 754
    ///
755 755
    /// Gives back a representant item of the component.
756 756
    Item item(int cls) const {
757 757
      return items[classes[cls].firstItem].item;
758 758
    }
759 759

	
760 760
    /// \brief Removes the given element from the structure.
761 761
    ///
762 762
    /// Removes the element from its component and if the component becomes
763 763
    /// empty then removes that component from the component list.
764 764
    ///
765 765
    /// \warning It is an error to remove an element which is not in
766 766
    /// the structure.
767 767
    void erase(const Item &item) {
768 768
      int idx = index[item];
769 769
      int cdx = items[idx].cls;
770 770

	
771 771
      if (idx == items[idx].next) {
772 772
        if (classes[cdx].prev != -1) {
773 773
          classes[classes[cdx].prev].next = classes[cdx].next;
774 774
        } else {
775 775
          firstClass = classes[cdx].next;
776 776
        }
777 777
        if (classes[cdx].next != -1) {
778 778
          classes[classes[cdx].next].prev = classes[cdx].prev;
779 779
        }
780 780
        classes[cdx].next = firstFreeClass;
781 781
        firstFreeClass = cdx;
782 782
      } else {
783 783
        classes[cdx].firstItem = items[idx].next;
784 784
        items[items[idx].next].prev = items[idx].prev;
785 785
        items[items[idx].prev].next = items[idx].next;
786 786
      }
787 787
      items[idx].next = firstFreeItem;
788 788
      firstFreeItem = idx;
789 789

	
790 790
    }
791 791

	
792 792

	
793 793
    /// \brief Removes the component of the given element from the structure.
794 794
    ///
795 795
    /// Removes the component of the given element from the structure.
796 796
    ///
797 797
    /// \warning It is an error to give an element which is not in the
798 798
    /// structure.
799 799
    void eraseClass(int cdx) {
800 800
      int idx = classes[cdx].firstItem;
801 801
      items[items[idx].prev].next = firstFreeItem;
802 802
      firstFreeItem = idx;
803 803

	
804 804
      if (classes[cdx].prev != -1) {
805 805
        classes[classes[cdx].prev].next = classes[cdx].next;
806 806
      } else {
807 807
        firstClass = classes[cdx].next;
808 808
      }
809 809
      if (classes[cdx].next != -1) {
810 810
        classes[classes[cdx].next].prev = classes[cdx].prev;
811 811
      }
812 812
      classes[cdx].next = firstFreeClass;
813 813
      firstFreeClass = cdx;
814 814
    }
815 815

	
816 816
    /// \brief LEMON style iterator for the classes.
817 817
    ///
818 818
    /// ClassIt is a lemon style iterator for the components. It iterates
819 819
    /// on the ids of classes.
820 820
    class ClassIt {
821 821
    public:
822 822
      /// \brief Constructor of the iterator
823 823
      ///
824 824
      /// Constructor of the iterator
825 825
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
826 826
        cdx = extendFind->firstClass;
827 827
      }
828 828

	
829 829
      /// \brief Constructor to get invalid iterator
830 830
      ///
831 831
      /// Constructor to get invalid iterator
832 832
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
833 833

	
834 834
      /// \brief Increment operator
835 835
      ///
836 836
      /// It steps to the next representant item.
837 837
      ClassIt& operator++() {
838 838
        cdx = extendFind->classes[cdx].next;
839 839
        return *this;
840 840
      }
841 841

	
842 842
      /// \brief Conversion operator
843 843
      ///
844 844
      /// It converts the iterator to the current class id.
845 845
      operator int() const {
846 846
        return cdx;
847 847
      }
848 848

	
849 849
      /// \brief Equality operator
850 850
      ///
851 851
      /// Equality operator
852 852
      bool operator==(const ClassIt& i) {
853 853
        return i.cdx == cdx;
854 854
      }
855 855

	
856 856
      /// \brief Inequality operator
857 857
      ///
858 858
      /// Inequality operator
859 859
      bool operator!=(const ClassIt& i) {
860 860
        return i.cdx != cdx;
861 861
      }
862 862

	
863 863
    private:
864 864
      const ExtendFindEnum* extendFind;
865 865
      int cdx;
866 866
    };
867 867

	
868 868
    /// \brief LEMON style iterator for the items of a component.
869 869
    ///
870 870
    /// ClassIt is a lemon style iterator for the components. It iterates
871 871
    /// on the items of a class. By example if you want to iterate on
872 872
    /// each items of each classes then you may write the next code.
873 873
    ///\code
874 874
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
875 875
    ///   std::cout << "Class: ";
876 876
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
877 877
    ///     std::cout << toString(iit) << ' ' << std::endl;
878 878
    ///   }
879 879
    ///   std::cout << std::endl;
880 880
    /// }
881 881
    ///\endcode
882 882
    class ItemIt {
883 883
    public:
884 884
      /// \brief Constructor of the iterator
885 885
      ///
886 886
      /// Constructor of the iterator. The iterator iterates
887 887
      /// on the class of the \c item.
888 888
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
889 889
        fdx = idx = extendFind->classes[cls].firstItem;
890 890
      }
891 891

	
892 892
      /// \brief Constructor to get invalid iterator
893 893
      ///
894 894
      /// Constructor to get invalid iterator
895 895
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
896 896

	
897 897
      /// \brief Increment operator
898 898
      ///
899 899
      /// It steps to the next item in the class.
900 900
      ItemIt& operator++() {
901 901
        idx = extendFind->items[idx].next;
902 902
        if (fdx == idx) idx = -1;
903 903
        return *this;
904 904
      }
905 905

	
906 906
      /// \brief Conversion operator
907 907
      ///
908 908
      /// It converts the iterator to the current item.
909 909
      operator const Item&() const {
910 910
        return extendFind->items[idx].item;
911 911
      }
912 912

	
913 913
      /// \brief Equality operator
914 914
      ///
915 915
      /// Equality operator
916 916
      bool operator==(const ItemIt& i) {
917 917
        return i.idx == idx;
918 918
      }
919 919

	
920 920
      /// \brief Inequality operator
921 921
      ///
922 922
      /// Inequality operator
923 923
      bool operator!=(const ItemIt& i) {
924 924
        return i.idx != idx;
925 925
      }
926 926

	
927 927
    private:
928 928
      const ExtendFindEnum* extendFind;
929 929
      int idx, fdx;
930 930
    };
931 931

	
932 932
  };
933 933

	
934 934
  /// \ingroup auxdat
935 935
  ///
936 936
  /// \brief A \e Union-Find data structure implementation which
937 937
  /// is able to store a priority for each item and retrieve the minimum of
938 938
  /// each class.
939 939
  ///
940 940
  /// A \e Union-Find data structure implementation which is able to
941 941
  /// store a priority for each item and retrieve the minimum of each
942 942
  /// class. In addition, it supports the joining and splitting the
943 943
  /// components. If you don't need this feature then you makes
944 944
  /// better to use the \ref UnionFind class which is more efficient.
945 945
  ///
946 946
  /// The union-find data strcuture based on a (2, 16)-tree with a
947 947
  /// tournament minimum selection on the internal nodes. The insert
948 948
  /// operation takes O(1), the find, set, decrease and increase takes
949 949
  /// O(log(n)), where n is the number of nodes in the current
950 950
  /// component.  The complexity of join and split is O(log(n)*k),
951 951
  /// where n is the sum of the number of the nodes and k is the
952 952
  /// number of joined components or the number of the components
953 953
  /// after the split.
954 954
  ///
955 955
  /// \pre You need to add all the elements by the \ref insert()
956 956
  /// method.
957 957
  template <typename V, typename IM, typename Comp = std::less<V> >
958 958
  class HeapUnionFind {
959 959
  public:
960 960

	
961 961
    ///\e
962 962
    typedef V Value;
963 963
    ///\e
964 964
    typedef typename IM::Key Item;
965 965
    ///\e
966 966
    typedef IM ItemIntMap;
967 967
    ///\e
968 968
    typedef Comp Compare;
969 969

	
970 970
  private:
971 971

	
972 972
    static const int cmax = 16;
973 973

	
974 974
    ItemIntMap& index;
975 975

	
976 976
    struct ClassNode {
977 977
      int parent;
978 978
      int depth;
979 979

	
980 980
      int left, right;
981 981
      int next, prev;
982 982
    };
983 983

	
984 984
    int first_class;
985 985
    int first_free_class;
986 986
    std::vector<ClassNode> classes;
987 987

	
988 988
    int newClass() {
989 989
      if (first_free_class < 0) {
990 990
        int id = classes.size();
991 991
        classes.push_back(ClassNode());
992 992
        return id;
993 993
      } else {
994 994
        int id = first_free_class;
995 995
        first_free_class = classes[id].next;
996 996
        return id;
997 997
      }
998 998
    }
0 comments (0 inline)