#include "mxbinarytree.h" // 0x101013f0 TreeNode *MxBinaryTree::g_Node_Nil = NULL; inline void MxBinaryTree::LeftRotate(TreeNode *x) { TreeNode *y = x->m_child1; x->m_child1 = y->m_child0; if (y->m_child0 != g_Node_Nil) y->m_child0->m_parent = x; y->m_parent = x->m_parent; if (m_root->m_parent != x) { if (x == x->m_parent->m_child0) { x->m_parent->m_child0 = y; y->m_child0 = x; //? x->m_parent = y; //? } else { x->m_parent->m_child1 = y; y->m_child1 = x; //? x->m_parent = y; //? } } else { // ? y->m_child0 = x; x->m_parent = y; } } inline void MxBinaryTree::RightRotate(TreeNode *x) { TreeNode *y = x->m_child0; x->m_child0 = y->m_child1; if (y->m_child1 != g_Node_Nil) y->m_child1->m_parent = x; y->m_parent = x->m_parent; if (m_root->m_parent != x) { if (x == x->m_parent->m_child1) { x->m_parent->m_child1 = y; y->m_child1 = x; //? x->m_parent = y; //? } else { x->m_parent->m_child0 = y; y->m_child0 = x; //? x->m_parent = y; //? } } else { //? y->m_child1 = x; x->m_parent = y; } } // OFFSET: LEGO1 0x100ad480 void mini_walk(TreeNode* &p_node) { if (p_node->m_color == NODE_COLOR_RED && p_node->m_parent->m_parent == p_node) { p_node = p_node->m_child1; return; } TreeNode *t = p_node->m_child0; if (t != MxBinaryTree::g_Node_Nil) { // wonky while (1) { if (t->m_child1 == MxBinaryTree::g_Node_Nil) break; t = t->m_child1; } p_node = t; return; } TreeNode *u = p_node->m_parent; TreeNode *v = p_node; while (u != v) { p_node = u; v = u; u = u->m_parent; } p_node = u; } // OFFSET: LEGO1 0x100ad4d0 void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_parent, TreeValue *&p_value) { TreeNode *node = new TreeNode(p_parent, NODE_COLOR_RED); node->m_child0 = g_Node_Nil; node->m_child1 = g_Node_Nil; // TODO: ??? if (node->m_value) { node->m_value = p_value; } this->m_p3++; // node count? // if tree is NOT empty // if param_2 is tree_nil (always true I think?) // if (this->m_root != p_parent && p_leaf == MxBinaryTree::g_Node_Nil && strcmp(p_value->m_str.GetData(), p_parent->m_value->m_str.GetData()) <= 0) { p_parent->m_child1 = node; if (m_root->m_child1 == p_parent) m_root->m_child1 = node; } else { p_parent->m_child0 = node; if (m_root != p_parent && m_root->m_child0 == p_parent) { m_root->m_child0 = p_parent; } else { m_root->m_parent = node; m_root->m_child1 = node; } } // LAB_100ad593 // rebalance?? TreeNode *cur = node; while (m_root->m_parent != cur) { TreeNode *parent = cur->m_parent; if (parent->m_color != NODE_COLOR_RED) break; TreeNode *grandparent = parent->m_parent; TreeNode *uncle = grandparent->m_child0; if (uncle == parent) { // wrong uncle uncle = grandparent->m_child1; if (uncle->m_color != NODE_COLOR_RED) { // 100ad5d3 if (parent->m_child1 == cur) { cur = parent; LeftRotate(cur); // rotate. /* parent->m_child1 = parent->m_child1->m_child0; // 100ad5e2 if (parent->m_child1 != g_Node_Nil) parent->m_child1->m_parent = cur; parent->m_child1->m_parent = grandparent; if (m_root->m_parent == cur || grandparent->m_child0 == cur) grandparent->m_child1 = parent; else grandparent->m_child0 = parent; parent->m_child0 = cur; grandparent->m_child0 = parent; */ } // LAB_100ad60f cur->m_parent->m_color = NODE_COLOR_BLACK; cur->m_parent->m_parent->m_color = NODE_COLOR_RED; RightRotate(cur->m_parent->m_parent); continue; } } else { // LAB_100ad67f if (uncle->m_color != NODE_COLOR_RED) { if (parent->m_child0 == cur) { cur = parent; RightRotate(cur); } // LAB_100ad60f cur->m_parent->m_color = NODE_COLOR_BLACK; cur->m_parent->m_parent->m_color = NODE_COLOR_RED; LeftRotate(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; cur = parent->m_parent; } m_root->m_parent->m_color = NODE_COLOR_BLACK; *p_output = node; } // OFFSET: LEGO1 0x100ad780 TreeNode *MxBinaryTree::Search(TreeValue*& p_value) { TreeNode *node_match = m_root; TreeNode *t_node = node_match->m_parent; while (t_node != g_Node_Nil) { int result = strcmp(t_node->m_value->m_str.GetData(), p_value->m_str.GetData()); if (result <= 0) { // if strings equal or less than search string // closest match? // it either does match or is where we will insert the new node. node_match = t_node; t_node = t_node->m_child0; } else { t_node = t_node->m_child1; } } return node_match; } // OFFSET: LEGO1 0x100ad7f0 void TreeValue::RefCountInc() { m_t0++; } // OFFSET: LEGO1 0x100ad800 void TreeValue::RefCountDec() { if (m_t0) m_t0--; }