diff --git a/LEGO1/mxbinarytree.cpp b/LEGO1/mxbinarytree.cpp index abfb5a36..7baa0b93 100644 --- a/LEGO1/mxbinarytree.cpp +++ b/LEGO1/mxbinarytree.cpp @@ -65,12 +65,12 @@ inline void MxBinaryTree::LeftRotate(TreeNode *x) } } -inline TreeNode *minimum(TreeNode *p_node) +inline TreeNode *MxBinaryTree::minimum(TreeNode *p_node) { // horrible. but it has to be this way to // force a non-branching JMP to repeat the loop. while (1) { - if (p_node->m_child1 == MxBinaryTree::g_Node_Nil) + if (p_node->m_child1 == g_Node_Nil) break; p_node = p_node->m_child1; } @@ -80,7 +80,7 @@ inline TreeNode *minimum(TreeNode *p_node) // OFFSET: LEGO1 0x100ad480 -void Successor(TreeNode* &p_node) +void MxBinaryTree::Successor(TreeNode* &p_node) { // I think this is checking whether this is the tree "root" node // i.e. MxBinaryTree->m_root @@ -88,13 +88,13 @@ void Successor(TreeNode* &p_node) // If it is the "root" node, return the minimum value of the tree. // We have a reference to it at m_root->m_child1. - if (p_node->m_color == NODE_COLOR_RED + if (p_node->m_color == RBNodeColor_Red && p_node->m_parent->m_parent == p_node) { p_node = p_node->m_child1; return; } - if (p_node->m_child0 != MxBinaryTree::g_Node_Nil) { + if (p_node->m_child0 != g_Node_Nil) { p_node = minimum(p_node->m_child0); return; } @@ -111,7 +111,7 @@ void Successor(TreeNode* &p_node) // OFFSET: LEGO1 0x100ad4d0 void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_parent, TreeValue *&p_value) { - TreeNode *node = newTreeNode(p_parent, NODE_COLOR_RED); + TreeNode *node = newTreeNode(p_parent, RBNodeColor_Red); node->m_child0 = g_Node_Nil; node->m_child1 = g_Node_Nil; @@ -125,7 +125,7 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par // if param_2 is tree_nil (always true I think?) // if (m_root != p_parent - && p_leaf == MxBinaryTree::g_Node_Nil + && p_leaf == g_Node_Nil && TreeValueCompare(p_value, p_parent->m_value)) { p_parent->m_child1 = node; @@ -152,7 +152,7 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par while (m_root->m_parent != cur) { TreeNode *parent = cur->m_parent; - if (parent->m_color != NODE_COLOR_RED) + if (parent->m_color != RBNodeColor_Red) break; TreeNode *uncle = parent->m_parent->m_child0; @@ -160,7 +160,7 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par // wrong uncle uncle = parent->m_parent->m_child1; - if (uncle->m_color != NODE_COLOR_RED) { + if (uncle->m_color != RBNodeColor_Red) { // 100ad5d3 if (parent->m_child1 == cur) { @@ -169,36 +169,36 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par } // LAB_100ad60f - cur->m_parent->m_color = NODE_COLOR_BLACK; - cur->m_parent->m_parent->m_color = NODE_COLOR_RED; + cur->m_parent->m_color = RBNodeColor_Black; + cur->m_parent->m_parent->m_color = RBNodeColor_Red; LeftRotate(cur->m_parent->m_parent); continue; } } else { // LAB_100ad67f - if (uncle->m_color != NODE_COLOR_RED) { + if (uncle->m_color != RBNodeColor_Red) { if (parent->m_child0 == cur) { cur = parent; LeftRotate(cur); } // LAB_100ad60f - cur->m_parent->m_color = NODE_COLOR_BLACK; - cur->m_parent->m_parent->m_color = NODE_COLOR_RED; + cur->m_parent->m_color = RBNodeColor_Black; + cur->m_parent->m_parent->m_color = RBNodeColor_Red; RightRotate(cur->m_parent->m_parent); continue; } } // LAB_100ad72c - parent->m_color = NODE_COLOR_BLACK; - uncle->m_color = NODE_COLOR_BLACK; - parent->m_parent->m_color = NODE_COLOR_RED; + parent->m_color = RBNodeColor_Black; + uncle->m_color = RBNodeColor_Black; + parent->m_parent->m_color = RBNodeColor_Red; cur = parent->m_parent; } - m_root->m_parent->m_color = NODE_COLOR_BLACK; + m_root->m_parent->m_color = RBNodeColor_Black; *p_output = node; } @@ -241,10 +241,10 @@ MxBinaryTree::~MxBinaryTree() } // OFFSET: LEGO1 0x100af7a0 -void somethingWithNode(TreeNode*& p_node) +void MxBinaryTree::Predecessor(TreeNode*& p_node) { // TODO - if (p_node->m_child1 != MxBinaryTree::g_Node_Nil) { + if (p_node->m_child1 != g_Node_Nil) { p_node = minimum(p_node->m_child1); return; } diff --git a/LEGO1/mxbinarytree.h b/LEGO1/mxbinarytree.h index 37d6851e..525fd7d5 100644 --- a/LEGO1/mxbinarytree.h +++ b/LEGO1/mxbinarytree.h @@ -3,9 +3,11 @@ #include "mxstring.h" -// TODO: enum instead? -#define NODE_COLOR_RED 0 -#define NODE_COLOR_BLACK 1 +enum RBNodeColor +{ + RBNodeColor_Red = 0, + RBNodeColor_Black = 1, +}; // SIZE 0x14 class TreeValue { @@ -31,11 +33,11 @@ class TreeNode { TreeNode *m_parent; // +4 // parent node TreeNode *m_child1; // +8 // string sorts before TreeValue *m_value; // +c - int m_color; // +10 // BLACK or RED. + RBNodeColor m_color; // +10 // BLACK or RED. }; // TODO: helper to avoid using a non-default constructor -inline TreeNode *newTreeNode(TreeNode *p_parent, int p_color) +inline TreeNode *newTreeNode(TreeNode *p_parent, RBNodeColor p_color) { TreeNode *t = new TreeNode(); t->m_parent = p_parent; @@ -43,17 +45,6 @@ inline TreeNode *newTreeNode(TreeNode *p_parent, int p_color) return t; } -// OFFSET: LEGO1 0x100ad120 -inline int TreeValueCompare(TreeValue *&p_val0, TreeValue *&p_val1) -{ - // For strcmp, a result greater than 0 means that b > a. - // So: for this function, return TRUE if: - // * string values are non-equal - // * string values are in order: p_val0 < p_val1 - - return strcmp(p_val0->m_str.GetData(), p_val1->m_str.GetData()) > 0; -} - // SIZE 0x10 class MxBinaryTree { @@ -63,18 +54,23 @@ class MxBinaryTree MxBinaryTree() { if (!g_Node_Nil) { - g_Node_Nil = newTreeNode(NULL, NODE_COLOR_BLACK); + g_Node_Nil = newTreeNode(NULL, RBNodeColor_Black); g_Node_Nil->m_child0 = NULL; g_Node_Nil->m_child1 = NULL; } - m_root = newTreeNode(g_Node_Nil, NODE_COLOR_RED); + m_root = newTreeNode(g_Node_Nil, RBNodeColor_Red); } ~MxBinaryTree(); void LeftRotate(TreeNode *); void RightRotate(TreeNode *); void Insert(TreeNode **, TreeNode *, TreeNode *, TreeValue *&); + void Successor(TreeNode* &p_node); + void Predecessor(TreeNode *&p_node); + int TreeValueCompare(TreeValue *&p_val0, TreeValue *&p_val1); + TreeNode *minimum(TreeNode *p_node); + TreeNode *maximum(TreeNode *p_node); TreeNode *Search(TreeValue *&); TreeNode *Find(TreeValue *&); @@ -84,6 +80,17 @@ class MxBinaryTree int m_nodeCount; // +c }; +// OFFSET: LEGO1 0x100ad120 +inline int MxBinaryTree::TreeValueCompare(TreeValue *&p_val0, TreeValue *&p_val1) +{ + // For strcmp, a result greater than 0 means that b > a. + // So: for this function, return TRUE if: + // * string values are non-equal + // * string values are in order: p_val0 < p_val1 + + return strcmp(p_val0->m_str.GetData(), p_val1->m_str.GetData()) > 0; +} + inline TreeNode *MxBinaryTree::Find(TreeValue *&p_value) { TreeNode *node = Search(p_value);