定位前驱节点和后继节点

时间:2017-03-24 23:09:47

标签: data-structures binary-search-tree

我有一个方法可以在二进制搜索树中获取后继节点和前导节点,但是我在代码中找到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"

1 个答案:

答案 0 :(得分:0)

我希望你的Node构造函数

new Node(key, d)

leftright字段设置为NULL

successorpredecessor我认为你的意思是 inorder遍历后继者和前身。那么你的代码对我来说似乎绝对没问题

唯一的可能性是我认为你使用常见变量prev和next 来获得前任和后继者。所以尝试为不同的节点使用不同的变量。

在完成节点B的后继和预取之后,定义新变量:

Node *prevK,*nextK;

并使用这些变量调用函数getNextAndPrev()