11_排序二叉树删除-3

来源:互联网 发布:金蝶数据库aix 编辑:程序博客网 时间:2024/06/05 15:49

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

 3 普通节点的删除

    3.1 删除的节点没有左子树,也没有右子树

     测试用例1: 删除节点6

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>     10 
  4. *        /  \                      \ 
  5. *      6     15                     15 
  6. *                                                          
  7. */  
  8.   
  9. static void test8()  
  10. {  
  11.     TREE_NODE* pTreeNode = NULL;  
  12.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  13.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  14.     assert(6 == pTreeNode->left_child->data);  
  15.     assert(TRUE == insert_node_into_tree(&pTreeNode, 15));  
  16.     assert(TRUE == delete_node_from_tree(&pTreeNode, 6));  
  17.     assert(NULL == pTreeNode->left_child);  
  18.     free(pTreeNode->right_child);  
  19.     free(pTreeNode);  
  20. }  
    测试用例2: 删除节点15

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>     10 
  4. *        /  \                    /  
  5. *      6     15                 6    
  6. *                                                          
  7. */  
  8.   
  9. static void test9()  
  10. {  
  11.     TREE_NODE* pTreeNode = NULL;  
  12.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  13.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  14.     assert(TRUE == insert_node_into_tree(&pTreeNode, 15));  
  15.     assert(15 == pTreeNode->right_child->data);  
  16.     assert(TRUE == delete_node_from_tree(&pTreeNode, 15));  
  17.     assert(NULL == pTreeNode->right_child);  
  18.     free(pTreeNode->right_child);  
  19.     free(pTreeNode);  
  20. }  
    那么代码应该怎么编写呢?

[cpp] view plaincopy
  1. STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)  
  2. {  
  3.     TREE_NODE* pLeftMax;  
  4.       
  5.     if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){  
  6.         if(pTreeNode == pTreeNode->parent->left_child)  
  7.             pTreeNode->parent->left_child = NULL;  
  8.         else  
  9.             pTreeNode->parent->right_child = NULL;  
  10.     }  
  11.       
  12.     free(pTreeNode);  
  13.     return TRUE;  
  14. }  

    3.2 删除的节点有左子树,没有右子树

    测试用例1: 测试节点6

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>     10 
  4. *        /                      /  
  5. *      6                      3    
  6. *     / 
  7. *    3                                                         
  8. */  
  9.   
  10. static void test10()  
  11. {  
  12.     TREE_NODE* pTreeNode = NULL;  
  13.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  14.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  15.     assert(TRUE == insert_node_into_tree(&pTreeNode, 3));  
  16.     assert(TRUE == delete_node_from_tree(&pTreeNode, 6));  
  17.     assert(3 == pTreeNode->left_child->data);  
  18.     assert(pTreeNode = pTreeNode->left_child->parent);  
  19.     free(pTreeNode->left_child);  
  20.     free(pTreeNode);  
  21. }  
    测试用例2: 删除节点15

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>     10 
  4. *           \                       \ 
  5. *           15                       12 
  6. *            /                     
  7. *           12                                                  
  8. */  
  9.   
  10. static void test11()  
  11. {  
  12.     TREE_NODE* pTreeNode = NULL;  
  13.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  14.     assert(TRUE == insert_node_into_tree(&pTreeNode, 15));  
  15.     assert(TRUE == insert_node_into_tree(&pTreeNode, 12));  
  16.     assert(TRUE == delete_node_from_tree(&pTreeNode, 15));  
  17.     assert(12 == pTreeNode->right_child->data);  
  18.     assert(pTreeNode = pTreeNode->right_child->parent);  
  19.     free(pTreeNode->right_child);  
  20.     free(pTreeNode);  
  21. }  
    添加左子树不为空,右子树为空的处理代码,如下所示:

[cpp] view plaincopy
  1. STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)  
  2. {  
  3.     TREE_NODE* pLeftMax;  
  4.       
  5.     if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){  
  6.         if(pTreeNode == pTreeNode->parent->left_child)  
  7.             pTreeNode->parent->left_child = NULL;  
  8.         else  
  9.             pTreeNode->parent->right_child = NULL;  
  10.     }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  11.         pTreeNode->left_child->parent = pTreeNode->parent;  
  12.           
  13.         if(pTreeNode == pTreeNode->parent->left_child)  
  14.             pTreeNode->parent->left_child = pTreeNode->left_child;  
  15.         else  
  16.             pTreeNode->parent->right_child = pTreeNode->left_child;  
  17.     }  
  18.       
  19.     free(pTreeNode);  
  20.     return TRUE;  
  21. }  

    3.3 删除的节点左子树为空,右子树节点不为空

    测试用例1: 删除数据6

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>    10 
  4. *        /                     /  
  5. *      6                      8    
  6. *       \ 
  7. *        8                                                     
  8. */  
  9.   
  10. static void test12()  
  11. {  
  12.     TREE_NODE* pTreeNode = NULL;  
  13.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  14.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  15.     assert(TRUE == insert_node_into_tree(&pTreeNode, 8));  
  16.     assert(TRUE == delete_node_from_tree(&pTreeNode, 6));  
  17.     assert(8 == pTreeNode->left_child->data);  
  18.     assert(pTreeNode = pTreeNode->left_child->parent);  
  19.     free(pTreeNode->left_child);  
  20.     free(pTreeNode);  
  21. }  
    测试用例2: 删除数据15

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *        10          ======>    10 
  4. *          \                      \  
  5. *           15                     20  
  6. *             \ 
  7. *             20                                              
  8. */  
  9.   
  10. static void test13()  
  11. {  
  12.     TREE_NODE* pTreeNode = NULL;  
  13.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  14.     assert(TRUE == insert_node_into_tree(&pTreeNode, 15));  
  15.     assert(TRUE == insert_node_into_tree(&pTreeNode, 20));  
  16.     assert(TRUE == delete_node_from_tree(&pTreeNode, 15));  
  17.     assert(20 == pTreeNode->right_child->data);  
  18.     assert(pTreeNode = pTreeNode->right_child->parent);  
  19.     free(pTreeNode->right_child);  
  20.     free(pTreeNode);  
  21. }  
    添加左子树为空,右子树不为空的处理情形。代码如下:

[cpp] view plaincopy
  1. STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)  
  2. {  
  3.     TREE_NODE* pLeftMax;  
  4.       
  5.     if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){  
  6.         if(pTreeNode == pTreeNode->parent->left_child)  
  7.             pTreeNode->parent->left_child = NULL;  
  8.         else  
  9.             pTreeNode->parent->right_child = NULL;  
  10.     }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  11.         pTreeNode->left_child->parent = pTreeNode->parent;  
  12.           
  13.         if(pTreeNode == pTreeNode->parent->left_child)  
  14.             pTreeNode->parent->left_child = pTreeNode->left_child;  
  15.         else  
  16.             pTreeNode->parent->right_child = pTreeNode->left_child;  
  17.     }else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){  
  18.         pTreeNode->right_child->parent = pTreeNode->parent;  
  19.           
  20.         if(pTreeNode == pTreeNode->parent->left_child)  
  21.             pTreeNode->parent->left_child = pTreeNode->right_child;  
  22.         else  
  23.             pTreeNode->parent->right_child = pTreeNode->right_child;  
  24.     }  
  25.       
  26.     free(pTreeNode);  
  27.     return TRUE;  
  28. }  

    3.4 删除的节点左右子树均不为空,不过又要分为两种情形:

    1) 左节点是删除节点左侧的最大节点 (删除节点6)

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>    10 
  4. *        /                     /  
  5. *      6                      5     
  6. *    /  \                      \ 
  7. *   5    8                      8                               
  8. */  
  9.   
  10. static void test14()  
  11. {  
  12.     TREE_NODE* pTreeNode = NULL;  
  13.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  14.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  15.     assert(TRUE == insert_node_into_tree(&pTreeNode, 5));  
  16.     assert(TRUE == insert_node_into_tree(&pTreeNode, 8));  
  17.     assert(TRUE == delete_node_from_tree(&pTreeNode, 6));  
  18.     assert(5 == pTreeNode->left_child->data);  
  19.     assert(pTreeNode = pTreeNode->left_child->parent);  
  20.     assert( 8 == pTreeNode->left_child->right_child->data);  
  21.     assert(pTreeNode->left_child = pTreeNode->left_child->right_child->parent);  
  22.     free(pTreeNode->left_child->right_child);  
  23.     free(pTreeNode->left_child);  
  24.     free(pTreeNode);  
  25. }  
    2) 左节点不是删除节点左侧的最大节点(删除节点5)

[cpp] view plaincopy
  1. /* 
  2. *                
  3. *         10          ======>    10 
  4. *        /                     /  
  5. *       5                      4     
  6. *      / \                    / \ 
  7. *     2   6                  2   6 
  8. *      \                                
  9. *       4 
  10. */  
  11.   
  12. static void test15()  
  13. {  
  14.     TREE_NODE* pTreeNode = NULL;  
  15.     assert(TRUE == insert_node_into_tree(&pTreeNode, 10));  
  16.     assert(TRUE == insert_node_into_tree(&pTreeNode, 5));  
  17.     assert(TRUE == insert_node_into_tree(&pTreeNode, 2));  
  18.     assert(TRUE == insert_node_into_tree(&pTreeNode, 4));  
  19.     assert(TRUE == insert_node_into_tree(&pTreeNode, 6));  
  20.     assert(TRUE == delete_node_from_tree(&pTreeNode, 5));  
  21.     assert(4 == pTreeNode->left_child->data);  
  22.     assert(NULL == pTreeNode->left_child->left_child->right_child);  
  23.     free(pTreeNode->left_child->left_child);  
  24.     free(pTreeNode->left_child->right_child);  
  25.     free(pTreeNode->left_child);  
  26.     free(pTreeNode);  
  27. }  
    那么针对这两种类型,我们的代码究竟应该怎么处理呢?

[cpp] view plaincopy
  1. STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)  
  2. {  
  3.     TREE_NODE* pLeftMax;  
  4.       
  5.     if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){  
  6.         if(pTreeNode == pTreeNode->parent->left_child)  
  7.             pTreeNode->parent->left_child = NULL;  
  8.         else  
  9.             pTreeNode->parent->right_child = NULL;  
  10.     }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  11.         pTreeNode->left_child->parent = pTreeNode->parent;  
  12.           
  13.         if(pTreeNode == pTreeNode->parent->left_child)  
  14.             pTreeNode->parent->left_child = pTreeNode->left_child;  
  15.         else  
  16.             pTreeNode->parent->right_child = pTreeNode->left_child;  
  17.     }else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){  
  18.         pTreeNode->right_child->parent = pTreeNode->parent;  
  19.           
  20.         if(pTreeNode == pTreeNode->parent->left_child)  
  21.             pTreeNode->parent->left_child = pTreeNode->right_child;  
  22.         else  
  23.             pTreeNode->parent->right_child = pTreeNode->right_child;  
  24.     }else{  
  25.         pLeftMax = find_max_node(pTreeNode->left_child);  
  26.         if(pLeftMax == pTreeNode->left_child){  
  27.               
  28.             if(pTreeNode == pTreeNode->parent->left_child)  
  29.                 pTreeNode->parent->left_child = pTreeNode->left_child;  
  30.             else  
  31.                 pTreeNode->parent->right_child = pTreeNode->left_child;  
  32.               
  33.             pTreeNode->left_child->parent = pTreeNode->parent;  
  34.             pTreeNode->left_child->right_child = pTreeNode->right_child;  
  35.             pTreeNode->right_child->parent = pTreeNode-> left_child;  
  36.               
  37.         }else{  
  38.             pTreeNode->data = pLeftMax->data;  
  39.             pLeftMax->parent->right_child = pLeftMax->left_child;  
  40.             pLeftMax->left_child->parent = pLeftMax->parent;  
  41.             pTreeNode = pLeftMax;  
  42.         }  
  43.     }  
  44.       
  45.     free(pTreeNode);  
  46.     return TRUE;  
  47. }  

结束总结:

    上面的过程记录了我们的代码是怎么一步一步走过来的。最后我们给出一份完整的节点删除代码:

[cpp] view plaincopy
  1. STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)  
  2. {  
  3.     TREE_NODE* pLeftMax;  
  4.       
  5.     if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){  
  6.         if(pTreeNode == pTreeNode->parent->left_child)  
  7.             pTreeNode->parent->left_child = NULL;  
  8.         else  
  9.             pTreeNode->parent->right_child = NULL;  
  10.     }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  11.         pTreeNode->left_child->parent = pTreeNode->parent;  
  12.           
  13.         if(pTreeNode == pTreeNode->parent->left_child)  
  14.             pTreeNode->parent->left_child = pTreeNode->left_child;  
  15.         else  
  16.             pTreeNode->parent->right_child = pTreeNode->left_child;  
  17.     }else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){  
  18.         pTreeNode->right_child->parent = pTreeNode->parent;  
  19.           
  20.         if(pTreeNode == pTreeNode->parent->left_child)  
  21.             pTreeNode->parent->left_child = pTreeNode->right_child;  
  22.         else  
  23.             pTreeNode->parent->right_child = pTreeNode->right_child;  
  24.     }else{  
  25.         pLeftMax = find_max_node(pTreeNode->left_child);  
  26.         if(pLeftMax == pTreeNode->left_child){  
  27.               
  28.             if(pTreeNode == pTreeNode->parent->left_child)  
  29.                 pTreeNode->parent->left_child = pTreeNode->left_child;  
  30.             else  
  31.                 pTreeNode->parent->right_child = pTreeNode->left_child;  
  32.               
  33.             pTreeNode->left_child->parent = pTreeNode->parent;  
  34.             pTreeNode->left_child->right_child = pTreeNode->right_child;  
  35.             pTreeNode->right_child->parent = pTreeNode-> left_child;  
  36.               
  37.         }else{  
  38.             pTreeNode->data = pLeftMax->data;  
  39.             pLeftMax->parent->right_child = pLeftMax->left_child;  
  40.             pLeftMax->left_child->parent = pLeftMax->parent;             
  41.             pTreeNode = pLeftMax;  
  42.         }  
  43.     }  
  44.       
  45.     free(pTreeNode);  
  46.     return TRUE;  
  47. }  
  48.   
  49. STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data)  
  50. {  
  51.     TREE_NODE* pTreeNode;  
  52.     TREE_NODE* pLeftMax;  
  53.       
  54.     if(NULL == ppTreeNode || NULL == *ppTreeNode)  
  55.         return FALSE;  
  56.       
  57.     pTreeNode = find_data_in_tree_node(*ppTreeNode, data);  
  58.     if(NULL == pTreeNode)  
  59.         return FALSE;  
  60.       
  61.     if(*ppTreeNode == pTreeNode){  
  62.           
  63.         if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){  
  64.             *ppTreeNode = NULL;  
  65.         }else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){  
  66.             *ppTreeNode = pTreeNode->left_child;  
  67.             pTreeNode->left_child->parent = NULL;  
  68.         }else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){  
  69.             *ppTreeNode = pTreeNode->right_child;  
  70.             pTreeNode->right_child->parent = NULL;  
  71.         }else{  
  72.             pLeftMax = find_max_node(pTreeNode->left_child);  
  73.             if(pLeftMax == pTreeNode->left_child){  
  74.                 *ppTreeNode = pTreeNode->left_child;  
  75.                 (*ppTreeNode)->right_child = pTreeNode->right_child;  
  76.                 (*ppTreeNode)->right_child->parent = *ppTreeNode;  
  77.                 (*ppTreeNode)->parent = NULL;  
  78.             }else{  
  79.                 pTreeNode->data = pLeftMax->data;  
  80.                 pLeftMax->parent->right_child = pLeftMax->left_child;  
  81.                 pLeftMax->left_child->parent = pLeftMax->parent;  
  82.                 pTreeNode = pLeftMax;  
  83.             }  
  84.         }  
  85.           
  86.         free(pTreeNode);  
  87.         return TRUE;  
  88.     }  
  89.       
  90.     return _delete_node_from_tree(pTreeNode);  
  91. }  
0 0