00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <qvdefines.h>
00026 #include <QVDisjointSet>
00027
00028 QVDisjointSet::QVDisjointSet(uInt numElements): cols(0), rows(0), elements(numElements)
00029 {
00030 Q_ASSERT_X(numElements > 0, "QVDisjointSet", "Number of elements equals 0 in constructor");
00031 allocData();
00032 makeSet();
00033 }
00034
00035 QVDisjointSet::QVDisjointSet(uInt cols, uInt rows): cols(cols), rows(rows), elements(cols*rows)
00036 {
00037 Q_ASSERT_X(cols > 0, "QVDisjointSet", "Number of columns equals 0 in constructor");
00038 Q_ASSERT_X(rows > 0, "QVDisjointSet", "Number of rows equals 0 in constructor");
00039 allocData();
00040 makeSet();
00041 }
00042
00043 QVDisjointSet::QVDisjointSet(const QVGenericImage &image): cols(image.getCols()), rows(image.getRows()), elements(cols*rows)
00044 {
00045 Q_ASSERT_X(cols > 0, "QVDisjointSet", "Number of columns equals 0 in constructor");
00046 Q_ASSERT_X(rows > 0, "QVDisjointSet", "Number of rows equals 0 in constructor");
00047 allocData();
00048 makeSet();
00049 }
00050
00051 QVDisjointSet::~QVDisjointSet()
00052 {
00053 Q_ASSERT_X(parent != 0, "~QVDisjointSet", "Parent array not allocated");
00054 Q_ASSERT_X(rank != 0, "~QVDisjointSet", "Rank array not allocated");
00055 freeData();
00056 }
00057
00058 const uInt QVDisjointSet::unify(uInt index1, uInt index2)
00059 {
00060 Q_ASSERT_X(index1 < elements, "QVDisjointSet::unify", "First index exceeds number of elements");
00061 Q_ASSERT_X(index2 < elements, "QVDisjointSet::unify", "Second index exceeds number of elements");
00062
00063
00064 if ( index1 == index2 )
00065 return index1;
00066
00067 uInt root1 = find(index1), root2 = find(index2);
00068
00069
00070 if ( root1 == root2 )
00071 return root1;
00072
00073
00074 sets--;
00075
00076 Q_ASSERT_X(sets > 0 , "QVDisjointSet::unify", "Number of sets reached 0");
00077
00078 if (rank[root1] > rank[root2])
00079 {
00080 uInt temp = root1;
00081 root1 = root2;
00082 root2 = temp;
00083 }
00084
00085 Q_ASSERT_X(rank[root1] == MIN(rank[root1], rank[root2]), "QVDisjointSet::unify", "first root is minimal");
00086 Q_ASSERT_X(rank[root2] == MAX(rank[root1], rank[root2]), "QVDisjointSet::unify", "first root is maximal");
00087
00088 if (rank[root1] == rank[root2])
00089 rank[root2] = rank[root2] +1;
00090
00091 parent[root1] = root2;
00092
00093
00094 count[root2] += count[root1];
00095
00096 Q_ASSERT_X(find(index1) == find(index2) , "QVDisjointSet::unify", "Parent for indexes don't coincide, after unify");
00097 Q_ASSERT_X(root2 == find(index1) , "QVDisjointSet::unify", "Root2 is not the root for elements.");
00098
00099 return root2;
00100 }
00101
00102 void QVDisjointSet::makeSet()
00103 {
00104 sets = elements;
00105 for (uInt index = 0; index < elements; index++)
00106 {
00107 rank[index] = 0;
00108 count[index] = 1;
00109 parent[index] = index;
00110 }
00111 }
00112
00113 void QVDisjointSet::allocData()
00114 {
00115 parent = new uInt[elements];
00116 rank = new uInt[elements];
00117 count = new uInt[elements];
00118 }
00119
00120 void QVDisjointSet::freeData()
00121 {
00122 delete parent;
00123 delete rank;
00124 delete count;
00125 }
00126