我正在为红黑树重载[]。每个节点包含四个元素:键,性别,身高和体重。 “键”值将被随机分配,并且应该是唯一的,因此我想通过遍历每个节点以查看“键”值是否已存在来重载[]。但是,它仅在只有一个节点的情况下起作用。这是代码:
#include<iostream>
#include<string>
using namespace std;
enum COLOR { RED, BLACK };
class Node
{
public:
Node(int key, string gender, int height, int weight, const COLOR & color = RED)
:pLeft(NULL), pRight(NULL), pParent(NULL), key(key), gender(gender), height(height), weight(weight), color(color)
{}
~Node();
string getGender();
int getHeight();
int getWeight();
Node* pLeft;
Node* pRight;
Node* pParent;
int key;
string gender;
int height;
int weight;
COLOR color;
};
class RBTree
{
public:
RBTree() :pRoot(NULL) {}
Node &operator[](int key);
bool insert(int key, string gender, int height, int weight);
void RotateL(Node* parent);
void RotateR(Node* parent);
void InOrder();
void InOrder(Node* pRoot);
Node* searchTree(Node* pRoot, int key);
bool CheckRBTree();
bool CheckRBTree(Node* pRoot,int counter,int k);
private:
Node* pRoot;
};
string Node::getGender()
{
return gender;
}
int Node::getHeight()
{
return height;
}
int Node::getWeight()
{
return weight;
}
Node &RBTree::operator[](int key)
{
Node* ptr = searchTree(pRoot, key);
return *ptr;
}
bool RBTree::insert(int key, string gender, int height, int weight)
{
// create root
if (pRoot == NULL)
{
pRoot = new Node(key, gender, height, weight);
pRoot->color = BLACK;
return true;
}
// find loc to insert
Node* pCur = pRoot;
Node* parent = NULL;
while (pCur)
{
if (key < pCur->key)
{
parent = pCur;
pCur = pCur->pLeft;
}
else if (key > pCur->key)
{
parent = pCur;
pCur = pCur->pRight;
}
else
return false;
}
// insert
pCur = new Node(key, gender, height, weight);
if (key < parent->key)
parent->pLeft = pCur;
else
parent->pRight = pCur;
pCur->pParent = parent;
// discuss 3 cases
while (pRoot != pCur&&pCur->pParent->color == RED)
{
Node* gf = parent->pParent;
if (gf->pLeft == parent)
{
Node* uncle = gf->pRight;
if (uncle&&uncle->color == RED)
{
parent->color = BLACK;
uncle->color = BLACK;
gf->color = RED;
pCur = gf;
parent = pCur->pParent;
}
else // turn case 3 into case 2
{
if (parent->pRight == pCur)
{
RotateL(parent);
std::swap(parent, pCur);
}
gf->color = RED;
parent->color = BLACK;
RotateR(gf);
}
}
else
{
Node*uncle = gf->pLeft;
if (uncle && uncle->color == RED) //case 1
{
parent->color = BLACK;
uncle->color = BLACK;
gf->color = RED;
pCur = gf;
parent = pCur->pParent;
}
else // turn case 3 into case 2
{
if (parent->pLeft == pCur)
{
RotateR(parent);
std::swap(parent, pCur);
}
gf->color = RED;
parent->color = BLACK;
RotateL(gf);
}
}
}
pRoot->color = BLACK;
return true;
}
// rotate left
void RBTree::RotateL(Node* parent)
{
Node* subR = parent->pRight;
Node* subRL = subR->pLeft;
parent->pRight = subRL;
if (subRL)
subRL->pParent = parent;
subR->pLeft = parent;
Node* gparent = parent->pParent;
parent->pParent = subR;
subR->pParent = gparent;
if (gparent == NULL)
pRoot = subR;
else if (gparent->pLeft == parent)
gparent->pLeft = subR;
else
gparent->pRight = subR;
}
void RBTree::RotateR(Node* parent)
{
Node* subL = parent->pLeft;
Node* subLR = subL->pRight;
parent->pLeft = subLR;
if (subLR)
subLR->pParent = parent;
subL->pRight = parent;
Node* gparent = parent->pParent;
parent->pParent = subL;
subL->pParent = gparent;
if (gparent == NULL)
pRoot = subL;
else if (gparent->pLeft == parent)
gparent->pLeft = subL;
else
gparent->pRight = subL;
}
void RBTree::InOrder()
{
cout << "InOrder: ";
InOrder(pRoot);
cout << endl;
}
void RBTree::InOrder(Node* pRoot)
{
if (pRoot)
{
InOrder(pRoot->pLeft);
cout << pRoot->key << " ";
InOrder(pRoot->pRight);
}
}
Node* RBTree::searchTree(Node* pRoot, int key)
{
if(pRoot->key == key)
return pRoot;
if(pRoot)
{
cout << "current node is " << pRoot->key << endl;
searchTree(pRoot->pLeft, key);
searchTree(pRoot->pRight, key);
}
return NULL;
}
bool RBTree::CheckRBTree()
{
if (pRoot == NULL)
return true;
if (pRoot->color == RED)
return false;
int blackcount = 0;
Node* pCur = pRoot;
while (pCur)
{
if (pCur->color == BLACK)
blackcount++;
pCur = pCur->pLeft;
}
return CheckRBTree(pRoot, blackcount, 0);
}
bool RBTree::CheckRBTree(Node* pRoot, int counter, int k)
{
if (pRoot == NULL)
return true;
if (pRoot->color == BLACK)
k++;
Node* parent = pRoot->pParent;
if (parent && parent->color == RED && pRoot->color == RED)
return false;
if (pRoot == NULL)
{
if (k != counter)
return false;
}
return CheckRBTree(pRoot->pLeft, counter, k)
&& CheckRBTree(pRoot->pRight, counter, k);
}
int main()
{
int a[] = { 10, 7, 8, 15, 5, 6, 11, 13, 12 };
RBTree t;
for (int index = 0; index < sizeof(a) / sizeof(a[0]); index++)
{
cout << a[index] << " ";
t.insert(a[index], "male", 12, 3);
}
cout << endl;
cout << t[7].getGender() << endl;
return 0;
}
有人知道如何解决此问题吗?预先感谢。
答案 0 :(得分:1)
您似乎还没有实现searchTree。
Node* RBTree::searchTree(Node* pRoot, int key)
{
if(pRoot->key == key)
return pRoot;
if(pRoot)
{
cout << "current node is " << pRoot->key << endl;
searchTree(pRoot->pLeft, key);
searchTree(pRoot->pRight, key);
}
return NULL;
}
如果根匹配,则返回根,而所有其他情况均返回NULL。那行不通。
注意:您使用pRoot->key
,并且仅在此之后检查if(pRoot)
。如果pRoot为NULL,那么您已经崩溃了。