我有一个方法可以在二进制搜索树中获取后继节点和前导节点,但是我在代码中找到bug时遇到了一些问题。假设我使用以下键添加节点:"C"
,"B"
和"K"
。如果我打印二叉搜索树的内容,我会得到以下输出:
"C" "some data 1"
"B" "some data 2"
"K" "some data 3"
当我添加"B"
时,它显然没有前任或后继,所以我只是将它们设置为空字符串:
root = root->insert(root, key, data);
root->getNextAndPrev(root, prev, next, key);
string p;
string n;
if (!prev) {
pred = "";
}
else {
pred = prev->getKey();
}
if (!next) {
succ = "";
}
else {
succ = next->getKey();
}
return new Entry(data, succ, pred);
当我添加"B"
时,我得到的输出"B"
的后继者是"C"
,前导符号是""
。但是,当我向树中添加"K"
时,我得到"K"
的前任为"C"
且后继也为"C"
的输出。我不确定为什么我收到此错误,因为我检查是否没有后继("K"
之后没有任何内容)将其设置为空字符串。
我的Node
班级处理insert()
和getNextAndPrev()
方法,以下是我实施这些方法的方法:
void Node::getNextAndPrev(Node* root, string key) {
if (!root) return;
if (root->key == key){
if (root->left != NULL){
Node* tempNode = root->left;
while (tempNode->right != NULL) {
tempNode = tempNode->right;
}
prev= tempNode;
}
if (root->right != NULL){
Node* tempNode = root->right;
while (tempNode->left != NULL) {
tempNode = tempNode->left;
}
next = tempNode;
}
}
if (root->key > key) {
next = root;
getNextAndPrev(root->left, key);
}
else {
prev = root;
getNextAndPrev(root->right, key);
}
}
为什么通过按顺序添加一些密钥导致我的getNextAndPrev
检索到错误的值?
也许这与我在main
中插入条目的方式有关。我有一个循环设置如下:
string command = "";
Entry* entry = new Entry("","","");
string def = "";
while (true) {
cout << "Enter command: ";
getline(cin, command);
if (parseCommand(command, "ADD") == 0) {
string tempCmd = processCommand(command, 3);
string key = tempCmd.substr(0, tempCmd.length() - 4);
string data = tempCmd.substr(tempCmd.length() - 4);
trim(key);
trim(data);
def = data;
entry = dict->modify(key, data);
cout << "added: " << key << " with definition of : " << def << " to the dictionary " << endl;
}
modify()
在我的Dictionary
类中被调用:
Entry * Dictionary::modify(string key, string data) {
Entry * entry = new Entry("","","");
if (root) entry = search(key);
//inserting something into the dictionary
if (data != "" && !this->root->doesContain(this->root, key)) {
root = root->insert(root, key, data);
return entry;
}
}
最后,我在search()
内调用的modify()
方法:
Entry * Dictionary::search(string key) {
if (key == "") {
return new Entry("", getSmallestKey(), getLargestKey());
}
if (!this->root->doesContain(root, key)) {
root->getNextAndPrev(root, key);
string prev;
string next;
if (root->getPrevNode() != NULL) {
prev = root->getPrevious();
cout << "Predecessor is " << prev << " root is: " << root->getKey() << endl;
}
else {
prev = "";
cout << "No Predecessor" << endl;
}
if (root->getNextNode() != NULL) {
next = root->getNext();
cout << "Successor is " << next << " root is: " << root->getKey() << endl;
}
else {
next = "";
cout << "No Successor" << endl;
}
if (next == prev) {
if (next < key) {
next = "";
}
if (prev > key) {
prev = "";
}
}
return new Entry("", next, prev);
}
为了详细说明问题,以下是运行上述内容的输出:
Enter command: ADD "FOO" "D"
lookup stuff: root: prev: next: // gets logged out when I insert into dictionary
added: "FOO" with a definition of: "D" to the dictionary
Enter command: ADD "BIN" "C"
No Predecessor
Successor is "FOO" root is: "FOO"
lookup stuff: root: prev: next: "FOO"
added: "BIN" with a definition of: "C" to the dictionary
Enter command: ADD "QUUX" "D"
Predecessor is "FOO" root is: "FOO"
Successor is "FOO" root is: "FOO"
lookup stuff: root: prev: "FOO" next:
added: "QUUX" with a definition of: "D" to the dictionary
Enter command: ADD "BAZ" "N"
Predecessor is "FOO" root is: "FOO"
Successor is "BIN" root is: "FOO"
lookup stuff: root: prev: "FOO" next: "BIN"
added: "BAZ" with a definition of: "N" to the dictionary
我无法弄清楚为什么在将BAZ
添加到词典时,前任和后继者现在已经不合适了:
Enter command: ADD "BAZ" "N"
Predecessor is "FOO" root is: "FOO"
Successor is "BIN" root is: "FOO"
答案 0 :(得分:0)
我希望你的Node构造函数
new Node(key, d)
将left
和right
字段设置为NULL
。
按successor
和predecessor
我认为你的意思是 inorder遍历后继者和前身。那么你的代码对我来说似乎绝对没问题
唯一的可能性是我认为你使用常见变量prev和next 来获得前任和后继者。所以尝试为不同的节点使用不同的变量。
在完成节点B的后继和预取之后,定义新变量:
Node *prevK,*nextK;
并使用这些变量调用函数getNextAndPrev()
。