mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-21 15:21:15 +00:00
Some cleanup. Make red-black node color an enum as promised.
Not converting to template class just yet, because we lose the ability to meaningfully compare the code using the reccmp tool. My plan is to get the functions as close as possible to a match, then change over at the final step.
This commit is contained in:
parent
8afddd3bdb
commit
c80744dfde
@ -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
|
// horrible. but it has to be this way to
|
||||||
// force a non-branching JMP to repeat the loop.
|
// force a non-branching JMP to repeat the loop.
|
||||||
while (1) {
|
while (1) {
|
||||||
if (p_node->m_child1 == MxBinaryTree::g_Node_Nil)
|
if (p_node->m_child1 == g_Node_Nil)
|
||||||
break;
|
break;
|
||||||
p_node = p_node->m_child1;
|
p_node = p_node->m_child1;
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ inline TreeNode *minimum(TreeNode *p_node)
|
|||||||
|
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100ad480
|
// 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 think this is checking whether this is the tree "root" node
|
||||||
// i.e. MxBinaryTree->m_root
|
// 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.
|
// If it is the "root" node, return the minimum value of the tree.
|
||||||
// We have a reference to it at m_root->m_child1.
|
// 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->m_parent->m_parent == p_node) {
|
||||||
p_node = p_node->m_child1;
|
p_node = p_node->m_child1;
|
||||||
return;
|
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);
|
p_node = minimum(p_node->m_child0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ void Successor(TreeNode* &p_node)
|
|||||||
// OFFSET: LEGO1 0x100ad4d0
|
// OFFSET: LEGO1 0x100ad4d0
|
||||||
void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_parent, TreeValue *&p_value)
|
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_child0 = g_Node_Nil;
|
||||||
node->m_child1 = 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 param_2 is tree_nil (always true I think?)
|
||||||
//
|
//
|
||||||
if (m_root != p_parent
|
if (m_root != p_parent
|
||||||
&& p_leaf == MxBinaryTree::g_Node_Nil
|
&& p_leaf == g_Node_Nil
|
||||||
&& TreeValueCompare(p_value, p_parent->m_value)) {
|
&& TreeValueCompare(p_value, p_parent->m_value)) {
|
||||||
p_parent->m_child1 = node;
|
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) {
|
while (m_root->m_parent != cur) {
|
||||||
TreeNode *parent = cur->m_parent;
|
TreeNode *parent = cur->m_parent;
|
||||||
|
|
||||||
if (parent->m_color != NODE_COLOR_RED)
|
if (parent->m_color != RBNodeColor_Red)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
TreeNode *uncle = parent->m_parent->m_child0;
|
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
|
// wrong uncle
|
||||||
uncle = parent->m_parent->m_child1;
|
uncle = parent->m_parent->m_child1;
|
||||||
|
|
||||||
if (uncle->m_color != NODE_COLOR_RED) {
|
if (uncle->m_color != RBNodeColor_Red) {
|
||||||
|
|
||||||
// 100ad5d3
|
// 100ad5d3
|
||||||
if (parent->m_child1 == cur) {
|
if (parent->m_child1 == cur) {
|
||||||
@ -169,36 +169,36 @@ void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_par
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LAB_100ad60f
|
// LAB_100ad60f
|
||||||
cur->m_parent->m_color = NODE_COLOR_BLACK;
|
cur->m_parent->m_color = RBNodeColor_Black;
|
||||||
cur->m_parent->m_parent->m_color = NODE_COLOR_RED;
|
cur->m_parent->m_parent->m_color = RBNodeColor_Red;
|
||||||
LeftRotate(cur->m_parent->m_parent);
|
LeftRotate(cur->m_parent->m_parent);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// LAB_100ad67f
|
// LAB_100ad67f
|
||||||
if (uncle->m_color != NODE_COLOR_RED) {
|
if (uncle->m_color != RBNodeColor_Red) {
|
||||||
if (parent->m_child0 == cur) {
|
if (parent->m_child0 == cur) {
|
||||||
cur = parent;
|
cur = parent;
|
||||||
LeftRotate(cur);
|
LeftRotate(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAB_100ad60f
|
// LAB_100ad60f
|
||||||
cur->m_parent->m_color = NODE_COLOR_BLACK;
|
cur->m_parent->m_color = RBNodeColor_Black;
|
||||||
cur->m_parent->m_parent->m_color = NODE_COLOR_RED;
|
cur->m_parent->m_parent->m_color = RBNodeColor_Red;
|
||||||
RightRotate(cur->m_parent->m_parent);
|
RightRotate(cur->m_parent->m_parent);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAB_100ad72c
|
// LAB_100ad72c
|
||||||
parent->m_color = NODE_COLOR_BLACK;
|
parent->m_color = RBNodeColor_Black;
|
||||||
uncle->m_color = NODE_COLOR_BLACK;
|
uncle->m_color = RBNodeColor_Black;
|
||||||
parent->m_parent->m_color = NODE_COLOR_RED;
|
parent->m_parent->m_color = RBNodeColor_Red;
|
||||||
|
|
||||||
cur = parent->m_parent;
|
cur = parent->m_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_root->m_parent->m_color = NODE_COLOR_BLACK;
|
m_root->m_parent->m_color = RBNodeColor_Black;
|
||||||
*p_output = node;
|
*p_output = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,10 +241,10 @@ MxBinaryTree::~MxBinaryTree()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100af7a0
|
// OFFSET: LEGO1 0x100af7a0
|
||||||
void somethingWithNode(TreeNode*& p_node)
|
void MxBinaryTree::Predecessor(TreeNode*& p_node)
|
||||||
{
|
{
|
||||||
// TODO
|
// 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);
|
p_node = minimum(p_node->m_child1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
#include "mxstring.h"
|
#include "mxstring.h"
|
||||||
|
|
||||||
// TODO: enum instead?
|
enum RBNodeColor
|
||||||
#define NODE_COLOR_RED 0
|
{
|
||||||
#define NODE_COLOR_BLACK 1
|
RBNodeColor_Red = 0,
|
||||||
|
RBNodeColor_Black = 1,
|
||||||
|
};
|
||||||
|
|
||||||
// SIZE 0x14
|
// SIZE 0x14
|
||||||
class TreeValue {
|
class TreeValue {
|
||||||
@ -31,11 +33,11 @@ class TreeNode {
|
|||||||
TreeNode *m_parent; // +4 // parent node
|
TreeNode *m_parent; // +4 // parent node
|
||||||
TreeNode *m_child1; // +8 // string sorts before
|
TreeNode *m_child1; // +8 // string sorts before
|
||||||
TreeValue *m_value; // +c
|
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
|
// 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();
|
TreeNode *t = new TreeNode();
|
||||||
t->m_parent = p_parent;
|
t->m_parent = p_parent;
|
||||||
@ -43,17 +45,6 @@ inline TreeNode *newTreeNode(TreeNode *p_parent, int p_color)
|
|||||||
return t;
|
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
|
// SIZE 0x10
|
||||||
class MxBinaryTree
|
class MxBinaryTree
|
||||||
{
|
{
|
||||||
@ -63,18 +54,23 @@ class MxBinaryTree
|
|||||||
MxBinaryTree()
|
MxBinaryTree()
|
||||||
{
|
{
|
||||||
if (!g_Node_Nil) {
|
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_child0 = NULL;
|
||||||
g_Node_Nil->m_child1 = 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();
|
~MxBinaryTree();
|
||||||
|
|
||||||
void LeftRotate(TreeNode *);
|
void LeftRotate(TreeNode *);
|
||||||
void RightRotate(TreeNode *);
|
void RightRotate(TreeNode *);
|
||||||
void Insert(TreeNode **, TreeNode *, TreeNode *, TreeValue *&);
|
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 *Search(TreeValue *&);
|
||||||
TreeNode *Find(TreeValue *&);
|
TreeNode *Find(TreeValue *&);
|
||||||
|
|
||||||
@ -84,6 +80,17 @@ class MxBinaryTree
|
|||||||
int m_nodeCount; // +c
|
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)
|
inline TreeNode *MxBinaryTree::Find(TreeValue *&p_value)
|
||||||
{
|
{
|
||||||
TreeNode *node = Search(p_value);
|
TreeNode *node = Search(p_value);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user