Original: Step by step write algorithm (sort binary Tree Delete-1)
"Disclaimer: Copyright, welcome reprint, please do not use for commercial purposes. Contact mailbox: feixiaoxing @163.com "
Compared to the addition of nodes, the deletion of balanced binary trees is more complicated. Because in the process of deletion, you have to take into account the different situations, for each different situation, you have to have targeted responses and adjustments. So in the process of code writing, we can write the test case while writing the code. Writing test cases can not only verify that the code we write is correct, but also improve our confidence in developing our code. This way, even if we modify or optimize the code during the development process, we are not afraid of it. However, it seems that writing test cases is a complicated process, but in terms of long-term profitability, the cost of writing test cases is very low.
What should we do in order to delete a binary tree? We do not have to worry, as long as we follow the following introduction step by step down to do it, broadly divided into the following three steps:
1) Judging the legality of the parameters, judging whether the parameters are in the current two-fork tree
2) Delete the node is the root node, at this time how to adjust
3) Delete the node is the normal node, at this time how to adjust
Gossip doesn't say much, let's see how our code is designed?
1, judge the legality of the parameters, and also determine whether the current two tree contains relevant data
1.1 Determining whether the input parameters are valid
STATUS Delete_node_from_tree (tree_node** pptreenode, int data) {if (NULL = = Pptreenode | | NULL = = *pptreenode) return False;return TRUE;}
So how do you write the test case at this point?
static void Test1 () {tree_node* Ptreenode = Null;assert (false = = Delete_node_from_tree (NULL, ten)); assert (false = = Delete_ Node_from_tree (&ptreenode, 10));}
Note: The above test case shows that the function returns False when the pointer is empty or the pointer is empty.
1.2 Determine if the input data exists
STATUS Delete_node_from_tree (tree_node** pptreenode, int data) {tree_node* ptreenode;if (NULL = = Pptreenode | | NULL = = *pptreenode) return False;ptreenode = Find_data_in_tree_node (*pptreenode, data); if (NULL = = Ptreenode) return False;return TRUE;}
At this point, we design a test case where the current pointer is valid, but delete the data that does not exist.
static void Test2 () {tree_node* Ptreenode = Null;ptreenode = Create_tree_node (n); assert (FALSE = = Delete_node_from_tree ( &ptreenode, one)); free (ptreenode);}
Note: The above test case root node is 10, but the deleted data is 11, step-tracked, to verify that the code we wrote is correct.
2, the deleted data is the root node data
2.1 root node does not have left subtree when deleting root data, there is no right child tree case
/** * ======> null* / * NULL null*/
So what should the code say at this point? We can give it a try.
STATUS Delete_node_from_tree (tree_node** pptreenode, int data) {tree_node* ptreenode;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;} Free (ptreenode); return TRUE;} return TRUE;}
Our code is obviously getting longer, and we need to be patient. At this point, it's time for us to add a new test case.
static void Test3 () {tree_node* Ptreenode = Null;ptreenode = Create_tree_node (ten); assert (TRUE = = Delete_node_from_tree (& Amp;ptreenode)); assert (NULL = = Ptreenode);}
2. 2 when deleting the root data, only the left Dial hand tree node, no right child tree node
/** * ======> 5* / \ / * 5 NULL 3 null* / * 3*/
Obviously, we just need to replace the original root node with the left Dial hand tree node.
STATUS Delete_node_from_tree (tree_node** pptreenode, int data) {tree_node* ptreenode;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;} Free (ptreenode); return TRUE;} return TRUE;}
At this point, we can add new test cases, add 10, 5, 3, and then delete 10.
static void Test4 () {tree_node* Ptreenode = Null;assert (true = = Insert_node_into_tree (&ptreenode, ten)); assert (true = = Insert_node_into_tree (&ptreenode, 5)); assert (true = = Insert_node_into_tree (&ptreenode, 3)); assert (true = = Delete_node_from_tree (&ptreenode)); assert (5 = = Ptreenode->data); assert (NULL = = ptreenode->parent); Free (ptreenode->left_child); free (ptreenode);}
2
. 3 When you delete the root data, there is no left subtree node, only the right child tree node
/** * ======> 15* / \ / * null + null 20* * 20*/
The above code indicates the deletion process of the node. We can follow this process to write code.
STATUS Delete_node_from_tree (tree_node** pptreenode, int data) {tree_node* ptreenode;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;} Free (ptreenode); return TRUE;} return TRUE;}
Add test cases, add 10, 15, 20, and then delete data 10.
static void Test5 () {tree_node* Ptreenode = Null;assert (true = = Insert_node_into_tree (&ptreenode, ten)); assert (true = = Insert_node_into_tree (&ptreenode, +)); assert (true = = Insert_node_into_tree (&ptreenode)); assert (true = = Delete_node_from_tree (&ptreenode)); assert (= = Ptreenode->data); assert (NULL = = ptreenode->parent); Free (ptreenode->right_child); free (ptreenode);}
2.4 The left and right nodes of the deleted data are present
adjourned
Step-by-step write algorithm (sort binary Tree Delete-1)