Update tree:
* fix swap and add an additional argument to swap or not the child * add sort functions for the children of a nodes
This commit is contained in:
1 parent
d04270ae3f
commit
5b7be93c1a
1 file changed
+79
-38
@@ -867,50 +867,65 @@ typedef int32_t m_tr33_index_t;
|
||||
return it1; \
|
||||
} \
|
||||
\
|
||||
static inline it_t \
|
||||
M_C(name, _swap_at)(it_t it1, it_t it2) { \
|
||||
M_ASSERT(it1.tree == it2.tree); \
|
||||
static inline void \
|
||||
M_C(name, _swap_at)(it_t it1, it_t it2, bool swapChild) { \
|
||||
M_ASSUME(it1.tree == it2.tree); \
|
||||
M_TR33_IT_CONTRACT(it1, true); \
|
||||
M_TR33_IT_CONTRACT(it2, true); \
|
||||
m_tr33_index_t tmp1, tmp2; \
|
||||
/* Swap left references */ \
|
||||
tmp1 = it1.tree->tab[it1.index].left; \
|
||||
tmp2 = it2.tree->tab[it2.index].left; \
|
||||
it1.tree->tab[it1.index].left = tmp2; \
|
||||
it2.tree->tab[it2.index].left = tmp1; \
|
||||
if (tmp1 >= 0) { it1.tree->tab[tmp1].right = it2.index; } \
|
||||
if (tmp2 >= 0) { it2.tree->tab[tmp2].right = it1.index; } \
|
||||
/* Swap right references */ \
|
||||
tmp1 = it1.tree->tab[it1.index].right; \
|
||||
tmp2 = it2.tree->tab[it2.index].right; \
|
||||
it1.tree->tab[it1.index].right = tmp2; \
|
||||
it2.tree->tab[it2.index].right = tmp1; \
|
||||
if (tmp1 >= 0) { it1.tree->tab[tmp1].left = it2.index; } \
|
||||
if (tmp2 >= 0) { it2.tree->tab[tmp2].left = it1.index; } \
|
||||
/* Swap down references */ \
|
||||
tmp1 = it1.tree->tab[it1.index].child; \
|
||||
tmp2 = it2.tree->tab[it2.index].child; \
|
||||
it1.tree->tab[it1.index].child = tmp2; \
|
||||
it2.tree->tab[it2.index].child = tmp1; \
|
||||
while (tmp1 >= 0) { \
|
||||
it1.tree->tab[tmp1].parent = it2.index; \
|
||||
tmp1 = it1.tree->tab[tmp1].right; \
|
||||
/* Read all references before modifying anything */ \
|
||||
m_tr33_index_t tmp1_l = it1.tree->tab[it1.index].left; \
|
||||
m_tr33_index_t tmp2_l = it2.tree->tab[it2.index].left; \
|
||||
m_tr33_index_t tmp1_r = it1.tree->tab[it1.index].right; \
|
||||
m_tr33_index_t tmp2_r = it2.tree->tab[it2.index].right; \
|
||||
m_tr33_index_t tmp1_d = it1.tree->tab[it1.index].child; \
|
||||
m_tr33_index_t tmp2_d = it2.tree->tab[it2.index].child; \
|
||||
m_tr33_index_t tmp1_u = it1.tree->tab[it1.index].parent; \
|
||||
m_tr33_index_t tmp2_u = it2.tree->tab[it2.index].parent; \
|
||||
/* Special cases if both nodes are siblings of the same node */ \
|
||||
if (tmp1_r == it2.index) { \
|
||||
M_ASSERT(tmp2_l == it1.index); \
|
||||
tmp1_r = it1.index; \
|
||||
tmp2_l = it2.index; \
|
||||
} \
|
||||
while (tmp2 >= 0) { \
|
||||
it2.tree->tab[tmp2].parent = it1.index; \
|
||||
tmp2 = it2.tree->tab[tmp2].right; \
|
||||
if (tmp2_r == it1.index) { \
|
||||
M_ASSERT(tmp1_l == it2.index); \
|
||||
tmp2_r = it2.index; \
|
||||
tmp1_l = it1.index; \
|
||||
} \
|
||||
/* Swap left references */ \
|
||||
it1.tree->tab[it1.index].left = tmp2_l; \
|
||||
it2.tree->tab[it2.index].left = tmp1_l; \
|
||||
if (tmp1_l >= 0) { it1.tree->tab[tmp1_l].right = it2.index; } \
|
||||
if (tmp2_l >= 0) { it2.tree->tab[tmp2_l].right = it1.index; } \
|
||||
/* Swap right references */ \
|
||||
it1.tree->tab[it1.index].right = tmp2_r; \
|
||||
it2.tree->tab[it2.index].right = tmp1_r; \
|
||||
if (tmp1_r >= 0) { it1.tree->tab[tmp1_r].left = it2.index; } \
|
||||
if (tmp2_r >= 0) { it2.tree->tab[tmp2_r].left = it1.index; } \
|
||||
/* Swap down references */ \
|
||||
if (swapChild == false) { \
|
||||
it1.tree->tab[it1.index].child = tmp2_d; \
|
||||
it2.tree->tab[it2.index].child = tmp1_d; \
|
||||
while (tmp1_d >= 0) { \
|
||||
it1.tree->tab[tmp1_d].parent = it2.index; \
|
||||
tmp1_d = it1.tree->tab[tmp1_d].right; \
|
||||
} \
|
||||
while (tmp2_d >= 0) { \
|
||||
it2.tree->tab[tmp2_d].parent = it1.index; \
|
||||
tmp2_d = it2.tree->tab[tmp2_d].right; \
|
||||
} \
|
||||
} \
|
||||
/* Swap up references */ \
|
||||
tmp1 = it1.tree->tab[it1.index].parent; \
|
||||
tmp2 = it2.tree->tab[it2.index].parent; \
|
||||
it1.tree->tab[it1.index].parent = tmp2; \
|
||||
it2.tree->tab[it2.index].parent = tmp1; \
|
||||
if (it1.tree->tab[tmp1].child == it1.index) { \
|
||||
it1.tree->tab[tmp1].child = it2.index; \
|
||||
it1.tree->tab[it1.index].parent = tmp2_u; \
|
||||
it2.tree->tab[it2.index].parent = tmp1_u; \
|
||||
if (tmp1_u >= 0 && it1.tree->tab[tmp1_u].child == it1.index) { \
|
||||
it1.tree->tab[tmp1_u].child = it2.index; \
|
||||
} \
|
||||
if (it2.tree->tab[tmp2].child == it2.index) { \
|
||||
it2.tree->tab[tmp2].child = it1.index; \
|
||||
else if (tmp2_u >= 0 && it2.tree->tab[tmp2_u].child == it2.index) { \
|
||||
it2.tree->tab[tmp2_u].child = it1.index; \
|
||||
} \
|
||||
M_TR33_IT_CONTRACT(it1, true); \
|
||||
M_TR33_IT_CONTRACT(it2, true); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
@@ -944,7 +959,33 @@ typedef int32_t m_tr33_index_t;
|
||||
} \
|
||||
M_TR33_IT_CONTRACT(it1, true); \
|
||||
M_TR33_IT_CONTRACT(it2, true); \
|
||||
}
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(CMP,oplist)( \
|
||||
static void \
|
||||
M_C(name, _sort_child)(it_t it0) { \
|
||||
M_TR33_IT_CONTRACT(it0, true); \
|
||||
it_t it1 = it0; \
|
||||
if (!M_C(name, _it_down)(&it1) ) return ; \
|
||||
/* Selection sort */ \
|
||||
do { \
|
||||
it_t it_min = it1; \
|
||||
it_t it2 = it1; \
|
||||
while (M_C(name, _it_right)(&it2)) { \
|
||||
if (M_CALL_CMP(oplist, *M_C(name, _cref)(it2), *M_C(name, _cref)(it_min)) < 0) { \
|
||||
it_min = it2; \
|
||||
} \
|
||||
} \
|
||||
if (M_C(name, _it_equal_p)(it_min, it1) == false) { \
|
||||
M_C(name, _swap_at)(it1, it_min, true); \
|
||||
/* The iterator it1 is no longer the min */ \
|
||||
it1 = it_min; \
|
||||
} \
|
||||
} while (M_C(name, _it_right)(&it1)); \
|
||||
M_TR33_IT_CONTRACT(it0, true); \
|
||||
} \
|
||||
, /* No CMP */ ) \
|
||||
|
||||
|
||||
// TODO:
|
||||
// * insertion function with move semantics (or _raw methods?)
|
||||
|
||||
Reference in new issue
Block a user