300 likes | 429 Vues
This guide outlines the process of deleting nodes from a Binary Search Tree (BST). It discusses the complexities involved in ensuring the tree remains valid after deletions, emphasizing the three main cases: deleting a leaf node, deleting a node with one child, and deleting a node with two children. Detailed implementation steps are provided, including code snippets for each case and links to resources for further learning. Mastering these deletion strategies is crucial for effective BST management.
E N D
Binary Search Trees IIIDelete Chapter 6
Objectives • You will be able to write code to delete a node from a Binary Search Tree.
Issues in Deletion from a BST • Deleting a node from a BST is more complex than adding a node. • We have to ensure that the BST is still a binary tree after we delete a node. • And that the BST constraints are still met. • Everything to the left of any node is <=. • Everything to the right of any node is >=.
Deletion from a BST Three possible cases for deleting a node, x, from a BST: 1. The node, x, is a leaf. 2. The node, x, has one child. 3. The node, x, has two children.
Deleting a Leaf Case 1. The node, x, is a leaf.
Deleting a Node with One Child Case 2. The node, x, has one child.
Deleting a Node with Two Children K • Case 3: The node, x, has two children. • Deletion by copying. (Hibbard & Knuth) Replace contents of x with the contents of its inorder successor Note that inorder successor will have no left child. Why?
Deleting a Node with Two Children Delete the former inorder successor node as described for cases 1 and 2 K The node that was the inorder successor will either be a leaf or have one child (a right child.) In this example it has a right child.
Implementing Deletion • Download most recent version of BST. • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_03_21_Delete_Node/ • BST_Vertical_Display • Expand. • Build and run. • Rename folder BST_with_Delete
Add Delete Node Method • In public section of BST class definition: void delete_node(const T&); • In protected section of BST class definition: void delete_leaf(BSTNode<T> *p, BSTNode<T> *prev); void delete_node_with_one_child(BSTNode<T> *p, BSTNode<T> *prev) ; void delete_node_with_two_children(BSTNode<T> *p) ;
Implementation • Copy: • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_03_21_Delete_Node/ File BST_Delete_Node.cpp.txt
Below Class Defintion template<class T> void BST<T>::delete_node(const T& el) { BSTNode<T> *p = root; BSTNode<T> *prev = 0; // Find node to be deleted. while (p != 0 && !(p->key == el)) { prev = p; if (p->key < el) { p = p->right; } else { p = p->left; } }
Delete Node Method (continued) if (p == 0) { // Declare success! cout << el << " is not in the tree\n"; return; } // p points to the node to be deleted. if ((p->left != 0) && (p->right != 0)) { // Delete node with two children abort(); // Not yet implemented } if ((p->left != 0) || (p->right != 0)) { // Delete node with one child. abort(); // Not yet implemented }
Delete Node Method (continued) // Delete leaf; delete_leaf(p, prev); }
delete_leaf() template<class T> void BST<T>::delete_leaf(BSTNode<T> *p, BSTNode<T> *prev) { cout << "Deleting leaf " << p->key << endl; if (prev->left == p) { prev->left = 0; } else { prev->right = 0; } delete(p); }
In main.cpp • Delete traversals. • Add at end: cout << endl << "Deleting 20\n"; my_BST.delete_node(20); cout << endl << "Updated tree:\n"; my_BST.display_v(cout); cin.get(); return 0; }
Delete Nonexistent Node • Add at end of main: cout << "\n\nDeleting nonexistent node, 15\n"; my_BST.delete_node(15); my_BST.display_v(cout); cout << endl << endl;
Delete Node with One Child • In function delete_node: if ((p->left != 0) || (p->right != 0)) { // Delete node with one child. delete_node_with_one_child(p, prev); return; } • Implementation: • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_03_21_Delete_Node/ • File delete_node_with_one_child.cpp.txt
Delete Node with One Child template<class T> void BST<T>::delete_node_with_one_child(BSTNode<T> *p, BSTNode<T> *prev) { cout << "Deleting node with one child, " << p->key << endl; BSTNode<T>* child; if (p->left != 0) { child = p->left; } else { child = p->right; } if (prev->right == p) { prev->right = child; } else { prev->left = child; } delete(p); }
main.cpp cout << "\nDeleting node with one child, 31\n"; my_BST.delete_node(31); cout << "\nUpdated tree:\n"; my_BST.display_v(cout); cout << endl << endl; cin.get(); return 0; }
Delete Node with Two Children In Function delete_node(): if ((p->left != 0) && (p->right != 0)) { // Delete node with two children delete_node_with_two_children(p); return; } Copy implementation from: http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_03_21_Delete_Node/ File delete_node_with_two_children.cpp.txt
Delete Node with Two Children template<class T> void BST<T>::delete_node_with_two_children(BSTNode<T> *p) { cout << "Deleting node with two children, " << p->key << endl; // Find inorder successor to node to be deleted. BSTNode<T>* suc = p->right; BSTNode<T>* prev = p; while (suc->left != 0) { prev = suc; suc = suc->left; }
Delete Node with Two Children // Copy data from inorder successor as data for the // node to be deleted. p->key = suc->key; // Delete the node that was the inorder successor. if (suc->right != 0) { // Delete node with one child. delete_node_with_one_child(suc, prev); } else { delete_leaf(suc, prev); } }
In main.cpp cout << "\nDeleting node with two children, 13\n"; my_BST.delete_node(13); cout << "\nUpdated tree:\n"; my_BST.display_v(cout); cout << endl << endl; cin.get(); return 0; }