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 uInt root1 = find(index1), root2 = find(index2);
00067
00068
00069 if ( (index1 == index2) || (root1 == root2) )
00070 return root1;
00071
00072
00073 sets--;
00074
00075 Q_ASSERT_X(sets > 0 , "QVDisjointSet::unify", "Number of sets reached 0");
00076
00077 if (rank[root1] > rank[root2])
00078 {
00079 uInt temp = root1;
00080 root1 = root2;
00081 root2 = temp;
00082 }
00083
00084 Q_ASSERT_X(rank[root1] == MIN(rank[root1], rank[root2]) ,
00085 "QVDisjointSet::unify", "first root is minimal");
00086 Q_ASSERT_X(rank[root2] == MAX(rank[root1], rank[root2]) ,
00087 "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 count[root2] += count[root1];
00094
00095 Q_ASSERT_X(find(index1) == find(index2) , "QVDisjointSet::unify",
00096 "Parent for indexes don't coincide, after unify");
00097
00098 return find(index1);
00099 }
00100
00101 void QVDisjointSet::makeSet()
00102 {
00103 sets = elements;
00104 for (uInt index = 0; index < elements; index++)
00105 {
00106 rank[index] = 0;
00107 count[index] = 1;
00108 parent[index] = index;
00109 }
00110 }
00111
00112 void QVDisjointSet::allocData()
00113 {
00114 parent = new uInt[elements];
00115 rank = new uInt[elements];
00116 count = new uInt[elements];
00117 }
00118
00119 void QVDisjointSet::freeData()
00120 {
00121 delete parent;
00122 delete rank;
00123 delete count;
00124 }
00125
00126 }