在二叉树中删除

时间:2018-06-22 06:21:05

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

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

  • 标识要删除的节点和最深的节点。
  • 用最深节点的数据替换其数据。
  • 删除最深的节点。

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

这是我的代码。

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);
    }
}

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

1 个答案:

答案 0 :(得分:0)

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

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);
    }

}

这样,您可以一次遍历父节点,现在可以相应地修改删除功能。