【问题标题】:Deletion in a Binary Tree二叉树中的删除
【发布时间】:2018-12-01 13:40:54
【问题描述】:

我一直在尝试在二叉树中实现删除。我知道这三个步骤是:

  • 识别要删除的节点和最深的节点。
  • 将其数据替换为最深节点的数据。
  • 删除最深的节点。

我必须遍历整棵树才能找到最深的节点。为了删除那个节点,我需要找到它的父节点。 有没有其他方法可以找到它的父节点而不必第二次遍历整个树?

这是我的代码。

tnode* searchNode(Tree &T, int data) {
    tnode* temp = nullptr;
    Queue Q;

    if(!T.root)
        return nullptr;

    enqueue(Q, T.root);
    while(!isEmptyQueue(Q)) {
        temp = dequeue(Q);

        if(temp->data == data) {
            return temp;
        }
        if(temp->left) {
            enqueue(Q, temp->left);
        }
        if(temp->right) {
            enqueue(Q, temp->right);
        }
    }
    return nullptr;
}

tnode* findDeepestNode(Tree &T) {
    tnode *temp = nullptr;
    Queue Q;

    if(!T.root)
        return nullptr;

    enqueue(Q, T.root);
    while(!isEmptyQueue(Q)) {
        temp = dequeue(Q);

        if(temp->left)
            enqueue(Q, temp->left);

        if(temp->right)
            enqueue(Q, temp->right);
    }
    return temp;
}

void removeNode(Tree &T, tnode *search) {
    tnode *temp = nullptr;
    tnode *del = nullptr;
    Queue Q;

    if(!T.root || T.root == search)
        return;

    enqueue(Q, T.root);
    while (!isEmptyQueue(Q)) {
        temp = dequeue(Q);

        if(temp->left) {
            if(temp->left == search) {
                del = temp->left;
                temp->left = nullptr;
                delete del;
                return;
            }
            else
                enqueue(Q, temp->left);
        }

        if(temp->right) {
            if(temp->right == search) {
                del = temp->right;
                temp->right = nullptr;
                delete del;
                return;
            }
            else
                enqueue(Q, temp->right);
        } 
    }
    return;
}

void deleteNode(Tree &T, int data) {
    tnode *search = searchNode(T, data);
    tnode *deepestnode = findDeepestNode(T);

    if(search) {
        search->data = deepestnode->data;
        removeNode(T, deepestnode);
    }
}

我刚刚开始学习数据结构。我写的代码似乎太长了。如何缩短此代码?如果我遵循任何不良的编码习惯,也请纠正我。

【问题讨论】:

  • 问题——为什么要用deepest节点替换要删除的节点,然后删除deepest节点?难道你不想简单地删除有问题的节点,然后将下一个叶节点移动到它的位置吗? (假设这不是一个可能需要旋转节点的平衡树
  • @DavidC.Rankin 叶节点也可以使用,但我使用最深的节点来保持二叉树的平衡。

标签: c++ algorithm data-structures binary-tree


【解决方案1】:

仅在此函数中,您也可以通过将双指针传递给最深节点及其父节点来找到最深节点和父节点:

tnode* searchNode(Tree &T, int data, tnode** deepest, tnode **parent) {
    tnode* temp = nullptr;
    tnode* searchNode = nullptr;
    Queue Q,parentQ;

    if(!T.root)
        return nullptr;

    enqueue(Q, T.root);
    enqueue(parentQ, nullptr);
    while(!isEmptyQueue(Q)) {
        temp = dequeue(Q);
        *parent = dequeue(parentQ);
        if(temp->data == data) {
            searchNode = temp;
        }
        if(temp->left) {
            enqueue(Q, temp->left);
            enqueue(parentQ, temp);
        }
        if(temp->right) {
            enqueue(Q, temp->right);
            enqueue(parentQ, temp);
        }
    }
    *deepest = temp;
    return searchNode;
}

修改deleteNode()函数为:

void deleteNode(Tree &T, int data) {
    tnode *deepestnode,*parent;
    tnode *search = searchNode(T, data, &deepestnode, &parent);

    if(search) {
        search->data = deepestnode->data;
        removeNode(T, deepestnode);
    }

}

这样,您可以在一次遍历中获取父节点,现在您可以相应地修改您的删除函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 2011-03-08
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多