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