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