排序二叉樹刪除2

來源:互聯網
上載者:User

   2.4 刪除節點的左右子樹都存在,此時又會分成兩種情形

    1)左節點是當前左子樹的最大節點,此時只需要用左節點代替根節點即可

 

/**               *         10          ======>     6*        /  \                   /   \*      6     15               5     15*     /                      *    5                         */

  代碼該怎麼編寫呢?

STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data){TREE_NODE* pTreeNode;TREE_NODE* pLeftMax;if(NULL == ppTreeNode || NULL == *ppTreeNode)return FALSE;pTreeNode = find_data_in_tree_node(*ppTreeNode, data);if(NULL == pTreeNode)return FALSE;if(*ppTreeNode == pTreeNode){if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){*ppTreeNode = NULL;}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){*ppTreeNode = pTreeNode->left_child;pTreeNode->left_child->parent = NULL;}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){*ppTreeNode = pTreeNode->right_child;pTreeNode->right_child->parent = NULL;}else{pLeftMax = find_max_node(pTreeNode->left_child);if(pLeftMax == pTreeNode->left_child){*ppTreeNode = pTreeNode->left_child;(*ppTreeNode)->right_child = pTreeNode->right_child;(*ppTreeNode)->right_child->parent = *ppTreeNode;(*ppTreeNode)->parent = NULL;}}free(pTreeNode);return TRUE;}return TRUE;}

上面的代碼中添加的內容表示了我們介紹的這一情形。為此,我們可以設計一種測試案例。依次插入10、6、5、15,然後刪除10即可。

static void test6(){TREE_NODE* pTreeNode = NULL;assert(TRUE == insert_node_into_tree(&pTreeNode, 10));assert(TRUE == insert_node_into_tree(&pTreeNode, 6));assert(TRUE == insert_node_into_tree(&pTreeNode, 5));assert(TRUE == insert_node_into_tree(&pTreeNode, 15));assert(TRUE == delete_node_from_tree(&pTreeNode, 10));assert(6 == pTreeNode->data);assert(NULL == pTreeNode->parent);assert(15 == pTreeNode->right_child->data);assert(pTreeNode = pTreeNode->right_child->parent);assert(NULL == pTreeNode->parent);free(pTreeNode->left_child);free(pTreeNode->right_child);free(pTreeNode);}

如果上面的測試案例通過,表示我們添加的代碼沒有問題。

2)左節點不是當前左子樹的最大節點,情形如下所示

 

/**               *         10          ======>     8*        /  \                   /   \*      6     15               5     15*       \                      *        8                     */

    此時,我們應該用10左側的最大節點8代替刪除的節點10即可。

 

STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data){TREE_NODE* pTreeNode;TREE_NODE* pLeftMax;if(NULL == ppTreeNode || NULL == *ppTreeNode)return FALSE;pTreeNode = find_data_in_tree_node(*ppTreeNode, data);if(NULL == pTreeNode)return FALSE;if(*ppTreeNode == pTreeNode){if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){*ppTreeNode = NULL;}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){*ppTreeNode = pTreeNode->left_child;pTreeNode->left_child->parent = NULL;}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){*ppTreeNode = pTreeNode->right_child;pTreeNode->right_child->parent = NULL;}else{pLeftMax = find_max_node(pTreeNode->left_child);if(pLeftMax == pTreeNode->left_child){*ppTreeNode = pTreeNode->left_child;(*ppTreeNode)->right_child = pTreeNode->right_child;(*ppTreeNode)->right_child->parent = *ppTreeNode;(*ppTreeNode)->parent = NULL;}else{pTreeNode->data = pLeftMax->data;pLeftMax->parent->right_child = NULL;pTreeNode = pLeftMax;}}free(pTreeNode);return TRUE;}return TRUE;}

  那麼,這個情境下面測試案例又該怎麼設計呢?其實只需要按照上面給出的進行即可。依次插入資料10、6、8、15,然後刪除資料10。

 

static void test7(){TREE_NODE* pTreeNode = NULL;assert(TRUE == insert_node_into_tree(&pTreeNode, 10));assert(TRUE == insert_node_into_tree(&pTreeNode, 6));assert(TRUE == insert_node_into_tree(&pTreeNode, 8));assert(TRUE == insert_node_into_tree(&pTreeNode, 15));assert(TRUE == delete_node_from_tree(&pTreeNode, 10));assert(8 == pTreeNode->data);assert(NULL == pTreeNode->parent);assert(NULL == pTreeNode->left_child->right_child);assert(NULL == pTreeNode->parent);free(pTreeNode->left_child);free(pTreeNode->right_child);free(pTreeNode);}

至此,刪除節點為根節點的情形全部討論完畢,那麼如果刪除的節點是普通節點呢,那應該怎麼解決呢?

STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data){TREE_NODE* pTreeNode;TREE_NODE* pLeftMax;if(NULL == ppTreeNode || NULL == *ppTreeNode)return FALSE;pTreeNode = find_data_in_tree_node(*ppTreeNode, data);if(NULL == pTreeNode)return FALSE;if(*ppTreeNode == pTreeNode){if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){*ppTreeNode = NULL;}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){*ppTreeNode = pTreeNode->left_child;pTreeNode->left_child->parent = NULL;}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){*ppTreeNode = pTreeNode->right_child;pTreeNode->right_child->parent = NULL;}else{pLeftMax = find_max_node(pTreeNode->left_child);if(pLeftMax == pTreeNode->left_child){*ppTreeNode = pTreeNode->left_child;(*ppTreeNode)->right_child = pTreeNode->right_child;(*ppTreeNode)->right_child->parent = *ppTreeNode;(*ppTreeNode)->parent = NULL;}else{pTreeNode->data = pLeftMax->data;pLeftMax->parent->right_child = pLeftMax->left_child;pTreeNode = pLeftMax;}}free(pTreeNode);return TRUE;}return _delete_node_from_tree(pTreeNode);}

我們在當前函數的最後一行添加_delete_node_from_tree,這個函數用來處理普通節點的刪除情況,我們會在下面一篇部落格中繼續介紹。

    3、 普通節點的刪除

    (待續)

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.