10_排序二叉树删除-2

来源:互联网 发布:mastercam自动编程 编辑:程序博客网 时间:2024/05/29 09:08

出处:http://blog.csdn.net/feixiaoxing/article/details/6867997

  2.4 删除节点的左右子树都存在,此时又会分成两种情形    

    1)左节点是当前左子树的最大节点,此时只需要用左节点代替根节点即可

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>     6 
  4. *        /  \                   /   \ 
  5. *      6     15               5     15 
  6. *     /                       
  7. *    5                          
  8. */  
    代码该怎么编写呢?

[cpp] view plaincopy
  1. STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data)  
  2. {  
  3.     TREE_NODE* pTreeNode;  
  4.     TREE_NODE* pLeftMax;  
  5.       
  6.     if(NULL == ppTreeNode || NULL == *ppTreeNode)  
  7.         return FALSE;  
  8.       
  9.     pTreeNode = find_data_in_tree_node(*ppTreeNode, data);  
  10.     if(NULL == pTreeNode)  
  11.         return FALSE;  
  12.       
  13.     if(*ppTreeNode == pTreeNode){  
  14.           
  15.         if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){  
  16.             *ppTreeNode = NULL;  
  17.         }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  18.             *ppTreeNode = pTreeNode->left_child;  
  19.             pTreeNode->left_child->parent = NULL;  
  20.         }else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){  
  21.             *ppTreeNode = pTreeNode->right_child;  
  22.             pTreeNode->right_child->parent = NULL;  
  23.         }else{  
  24.             pLeftMax = find_max_node(pTreeNode->left_child);  
  25.             if(pLeftMax == pTreeNode->left_child){  
  26.                 *ppTreeNode = pTreeNode->left_child;  
  27.                 (*ppTreeNode)->right_child = pTreeNode->right_child;  
  28.                 (*ppTreeNode)->right_child->parent = *ppTreeNode;  
  29.                 (*ppTreeNode)->parent = NULL;  
  30.             }  
  31.         }  
  32.           
  33.         free(pTreeNode);  
  34.         return TRUE;  
  35.     }  
  36.       
  37.     return TRUE;  
  38. }  
    上面的代码中添加的内容表示了我们介绍的这一情形。为此,我们可以设计一种测试用例。依次插入10、6、5、15,然后删除10即可。

[cpp] view plaincopy
  1. static void test6()  
  2. {  
  3.     TREE_NODE* pTreeNode = NULL;  
  4.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  5.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  6.     assert(TRUE == insert_node_into_tree(&pTreeNode, 5));  
  7.     assert(TRUE == insert_node_into_tree(&pTreeNode, 15));  
  8.     assert(TRUE == delete_node_from_tree(&pTreeNode, 10));  
  9.     assert(6 == pTreeNode->data);  
  10.     assert(NULL == pTreeNode->parent);  
  11.     assert(15 == pTreeNode->right_child->data);  
  12.     assert(pTreeNode = pTreeNode->right_child->parent);  
  13.     assert(NULL == pTreeNode->parent);  
  14.     free(pTreeNode->left_child);  
  15.     free(pTreeNode->right_child);  
  16.     free(pTreeNode);  
  17. }  
    如果上面的测试用例通过,表示我们添加的代码没有问题。


    2)左节点不是当前左子树的最大节点,情形如下所示

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>     8 
  4. *        /  \                   /   \ 
  5. *      6     15               5     15 
  6. *       \                       
  7. *        8                      
  8. */  
    此时,我们应该用10左侧的最大节点8代替删除的节点10即可。

[cpp] view plaincopy
  1. STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data)  
  2. {  
  3.     TREE_NODE* pTreeNode;  
  4.     TREE_NODE* pLeftMax;  
  5.       
  6.     if(NULL == ppTreeNode || NULL == *ppTreeNode)  
  7.         return FALSE;  
  8.       
  9.     pTreeNode = find_data_in_tree_node(*ppTreeNode, data);  
  10.     if(NULL == pTreeNode)  
  11.         return FALSE;  
  12.       
  13.     if(*ppTreeNode == pTreeNode){  
  14.           
  15.         if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){  
  16.             *ppTreeNode = NULL;  
  17.         }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  18.             *ppTreeNode = pTreeNode->left_child;  
  19.             pTreeNode->left_child->parent = NULL;  
  20.         }else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){  
  21.             *ppTreeNode = pTreeNode->right_child;  
  22.             pTreeNode->right_child->parent = NULL;  
  23.         }else{  
  24.             pLeftMax = find_max_node(pTreeNode->left_child);  
  25.             if(pLeftMax == pTreeNode->left_child){  
  26.                 *ppTreeNode = pTreeNode->left_child;  
  27.                 (*ppTreeNode)->right_child = pTreeNode->right_child;  
  28.                 (*ppTreeNode)->right_child->parent = *ppTreeNode;  
  29.                 (*ppTreeNode)->parent = NULL;  
  30.             }else{  
  31.                 pTreeNode->data = pLeftMax->data;  
  32.                 pLeftMax->parent->right_child = NULL;  
  33.                 pTreeNode = pLeftMax;  
  34.             }  
  35.         }  
  36.           
  37.         free(pTreeNode);  
  38.         return TRUE;  
  39.     }  
  40.       
  41.     return TRUE;  
  42. }  
    那么,这个场景下面测试用例又该怎么设计呢?其实只需要按照上面给出的示意图进行即可。依次插入数据10、6、8、15,然后删除数据10。

[cpp] view plaincopy
  1. static void test7()  
  2. {  
  3.     TREE_NODE* pTreeNode = NULL;  
  4.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  5.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  6.     assert(TRUE == insert_node_into_tree(&pTreeNode, 8));  
  7.     assert(TRUE == insert_node_into_tree(&pTreeNode, 15));  
  8.     assert(TRUE == delete_node_from_tree(&pTreeNode, 10));  
  9.     assert(8 == pTreeNode->data);  
  10.     assert(NULL == pTreeNode->parent);  
  11.     assert(NULL == pTreeNode->left_child->right_child);  
  12.     assert(NULL == pTreeNode->parent);  
  13.     free(pTreeNode->left_child);  
  14.     free(pTreeNode->right_child);  
  15.     free(pTreeNode);  
  16. }  
    至此,删除节点为根节点的情形全部讨论完毕,那么如果删除的节点是普通节点呢,那应该怎么解决呢?

[cpp] view plaincopy
  1. STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data)  
  2. {  
  3.     TREE_NODE* pTreeNode;  
  4.     TREE_NODE* pLeftMax;  
  5.       
  6.     if(NULL == ppTreeNode || NULL == *ppTreeNode)  
  7.         return FALSE;  
  8.       
  9.     pTreeNode = find_data_in_tree_node(*ppTreeNode, data);  
  10.     if(NULL == pTreeNode)  
  11.         return FALSE;  
  12.       
  13.     if(*ppTreeNode == pTreeNode){  
  14.           
  15.         if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){  
  16.             *ppTreeNode = NULL;  
  17.         }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  18.             *ppTreeNode = pTreeNode->left_child;  
  19.             pTreeNode->left_child->parent = NULL;  
  20.         }else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){  
  21.             *ppTreeNode = pTreeNode->right_child;  
  22.             pTreeNode->right_child->parent = NULL;  
  23.         }else{  
  24.             pLeftMax = find_max_node(pTreeNode->left_child);  
  25.             if(pLeftMax == pTreeNode->left_child){  
  26.                 *ppTreeNode = pTreeNode->left_child;  
  27.                 (*ppTreeNode)->right_child = pTreeNode->right_child;  
  28.                 (*ppTreeNode)->right_child->parent = *ppTreeNode;  
  29.                 (*ppTreeNode)->parent = NULL;  
  30.             }else{  
  31.                 pTreeNode->data = pLeftMax->data;  
  32.                 pLeftMax->parent->right_child = pLeftMax->left_child;  
  33.                 pLeftMax->left_child->parent = pLeftMax->parent;  
  34.                 pTreeNode = pLeftMax;  
  35.             }  
  36.         }  
  37.           
  38.         free(pTreeNode);  
  39.         return TRUE;  
  40.     }  
  41.       
  42.     return _delete_node_from_tree(pTreeNode);  
  43. }  
    我们在当前函数的最后一行添加_delete_node_from_tree,这个函数用来处理普通节点的删除情况,我们会在下面一篇博客中继续介绍。


    3、 普通节点的删除


0 0