Lecture No 16 Data Structures Dr Sohail Aslam

  • Slides: 37
Download presentation
Lecture No. 16 Data Structures Dr. Sohail Aslam

Lecture No. 16 Data Structures Dr. Sohail Aslam

Deleting a node in BST § As is common with many data structures, the

Deleting a node in BST § As is common with many data structures, the hardest operation is deletion. § Once we have found the node to be deleted, we need to consider several possibilities. § If the node is a leaf, it can be deleted immediately.

Deleting a node in BST § If the node has one child, the node

Deleting a node in BST § If the node has one child, the node can be deleted after its parent adjusts a pointer to bypass the node and connect to inorder successor. 6 2 1 8 4 3

Deleting a node in BST § The inorder traversal order has to be maintained

Deleting a node in BST § The inorder traversal order has to be maintained after the delete. 6 2 1 8 4 3 6 2 1 8 4 3

Deleting a node in BST § The inorder traversal order has to be maintained

Deleting a node in BST § The inorder traversal order has to be maintained after the delete. 6 2 1 8 4 3 6 2 1 8 3

Deleting a node in BST § The complicated case is when the node to

Deleting a node in BST § The complicated case is when the node to be deleted has both left and right subtrees. § The strategy is to replace the data of this node with the smallest data of the right subtree and recursively delete that node.

Deleting a node in BST Delete(2): locate inorder successor 6 2 1 8 5

Deleting a node in BST Delete(2): locate inorder successor 6 2 1 8 5 3 Inorder successor 4

Deleting a node in BST Delete(2): locate inorder successor 6 2 1 8 5

Deleting a node in BST Delete(2): locate inorder successor 6 2 1 8 5 3 Inorder successor § Inorder successor will be the left-most node in the right subtree of 2. 4 § The inorder successor will not have a left child because if it did, that child would be the left-most node.

Deleting a node in BST Delete(2): copy data from inorder successor 6 2 1

Deleting a node in BST Delete(2): copy data from inorder successor 6 2 1 8 5 3 6 3 1 8 5 3 4 4

Deleting a node in BST Delete(2): remove the inorder successor 6 2 1 8

Deleting a node in BST Delete(2): remove the inorder successor 6 2 1 8 5 3 3 1 8 5 3 4 6 6 3 1 8 5 3 4 4

Deleting a node in BST Delete(2) 6 3 1 6 8 5 3 3

Deleting a node in BST Delete(2) 6 3 1 6 8 5 3 3 1 5 4 4 8

C++ code for delete § ‘delete’ is C++ keyword. We will call our delete.

C++ code for delete § ‘delete’ is C++ keyword. We will call our delete. Node routine remove. § Here is the C++ code for remove.

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>*

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>* t; int cmp = info - *(tree->get. Info()); if( cmp < 0 ){ t = remove(tree->get. Left(), info); tree->set. Left( t ); } else if( cmp > 0 ){ t = remove(tree->get. Right(), info); tree->set. Right( t ); }

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>*

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>* t; int cmp = info - *(tree->get. Info()); if( cmp < 0 ){ t = remove(tree->get. Left(), info); tree->set. Left( t ); } else if( cmp > 0 ){ t = remove(tree->get. Right(), info); tree->set. Right( t ); }

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>*

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>* t; int cmp = info - *(tree->get. Info()); if( cmp < 0 ){ t = remove(tree->get. Left(), info); tree->set. Left( t ); } else if( cmp > 0 ){ t = remove(tree->get. Right(), info); tree->set. Right( t ); }

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>*

C++ code for delete Tree. Node<int>* remove(Tree. Node<int>* tree, int info) { Tree. Node<int>* t; int cmp = info - *(tree->get. Info()); if( cmp < 0 ){ t = remove(tree->get. Left(), info); tree->set. Left( t ); } else if( cmp > 0 ){ t = remove(tree->get. Right(), info); tree->set. Right( t ); }

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() !=

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() != NULL && tree->get. Right() != NULL ){ Tree. Node<int>* min. Node; min. Node = find. Min(tree->get. Right()); tree->set. Info( min. Node->get. Info() ); t = remove(tree->get. Right(), *(min. Node->get. Info())); tree->set. Right( t ); }

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() !=

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() != NULL && tree->get. Right() != NULL ){ Tree. Node<int>* min. Node; min. Node = find. Min(tree->get. Right()); tree->set. Info( min. Node->get. Info() ); t = remove(tree->get. Right(), *(min. Node->get. Info())); tree->set. Right( t ); }

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() !=

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() != NULL && tree->get. Right() != NULL ){ Tree. Node<int>* min. Node; min. Node = find. Min(tree->get. Right()); tree->set. Info( min. Node->get. Info() ); t = remove(tree->get. Right(), *(min. Node->get. Info())); tree->set. Right( t ); }

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() !=

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() != NULL && tree->get. Right() != NULL ){ Tree. Node<int>* min. Node; min. Node = find. Min(tree->get. Right()); tree->set. Info( min. Node->get. Info() ); t = remove(tree->get. Right(), *(min. Node->get. Info())); tree->set. Right( t ); }

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() !=

C++ code for delete //two children, replace with inorder successor else if(tree->get. Left() != NULL && tree->get. Right() != NULL ){ Tree. Node<int>* min. Node; min. Node = find. Min(tree->get. Right()); tree->set. Info( min. Node->get. Info() ); t = remove(tree->get. Right(), *(min. Node->get. Info())); tree->set. Right( t ); }

C++ code for delete else { // case 1 Tree. Node<int>* node. To. Delete

C++ code for delete else { // case 1 Tree. Node<int>* node. To. Delete = tree; if( tree->get. Left() == NULL ) //will handle 0 children tree = tree->get. Right(); else if( tree->get. Right() == NULL ) tree = tree->get. Left(); else tree = NULL; delete node. To. Delete; } return tree; }

C++ code for delete else { // case 1 Tree. Node<int>* node. To. Delete

C++ code for delete else { // case 1 Tree. Node<int>* node. To. Delete = tree; if( tree->get. Left() == NULL ) //will handle 0 children tree = tree->get. Right(); else if( tree->get. Right() == NULL ) tree = tree->get. Left(); else tree = NULL; delete node. To. Delete; } return tree; }

C++ code for delete else { // case 1 Tree. Node<int>* node. To. Delete

C++ code for delete else { // case 1 Tree. Node<int>* node. To. Delete = tree; if( tree->get. Left() == NULL ) //will handle 0 children tree = tree->get. Right(); else if( tree->get. Right() == NULL ) tree = tree->get. Left(); else tree = NULL; delete node. To. Delete; } return tree; }

C++ code for delete Tree. Node<int>* find. Min(Tree. Node<int>* tree) { if( tree ==

C++ code for delete Tree. Node<int>* find. Min(Tree. Node<int>* tree) { if( tree == NULL ) return NULL; if( tree->get. Left() == NULL ) return tree; // this is it. return find. Min( tree->get. Left() ); }

C++ code for delete Tree. Node<int>* find. Min(Tree. Node<int>* tree) { if( tree ==

C++ code for delete Tree. Node<int>* find. Min(Tree. Node<int>* tree) { if( tree == NULL ) return NULL; if( tree->get. Left() == NULL ) return tree; // this is it. return find. Min( tree->get. Left() ); }

C++ code for delete Tree. Node<int>* find. Min(Tree. Node<int>* tree) { if( tree ==

C++ code for delete Tree. Node<int>* find. Min(Tree. Node<int>* tree) { if( tree == NULL ) return NULL; if( tree->get. Left() == NULL ) return tree; // this is it. return find. Min( tree->get. Left() ); }

Binary. Search. Tree. h Let us design the Binary. Search. Tree class (factory).

Binary. Search. Tree. h Let us design the Binary. Search. Tree class (factory).

Binary. Search. Tree. h #ifndef _BINARY_SEARCH_TREE_H_ #define _BINARY_SEARCH_TREE_H_ #include <iostream. h> // For NULL

Binary. Search. Tree. h #ifndef _BINARY_SEARCH_TREE_H_ #define _BINARY_SEARCH_TREE_H_ #include <iostream. h> // For NULL // Binary node and forward declaration template <class EType> class Binary. Search. Tree;

Binary. Search. Tree. h #ifndef _BINARY_SEARCH_TREE_H_ #define _BINARY_SEARCH_TREE_H_ #include <iostream. h> // For NULL

Binary. Search. Tree. h #ifndef _BINARY_SEARCH_TREE_H_ #define _BINARY_SEARCH_TREE_H_ #include <iostream. h> // For NULL // Binary node and forward declaration template <class EType> class Binary. Search. Tree;

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary.

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary. Node *left; Binary. Node *right; Binary. Node( const EType & the. Element, Binary. Node *lt, Binary. Node *rt ) : element( the. Element ), left( lt ), right( rt ) { } friend class Binary. Search. Tree<EType>; };

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary.

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary. Node *left; Binary. Node *right; Binary. Node( const EType & the. Element, Binary. Node *lt, Binary. Node *rt ) : element( the. Element ), left( lt ), right( rt ) { } friend class Binary. Search. Tree<EType>; };

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary.

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary. Node *left; Binary. Node *right; Binary. Node( const EType & the. Element, Binary. Node *lt, Binary. Node *rt ) : element( the. Element ), left( lt ), right( rt ) { } friend class Binary. Search. Tree<EType>; };

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary.

Binary. Search. Tree. h template <class EType> class Binary. Node { EType element; Binary. Node *left; Binary. Node *right; Binary. Node( const EType & the. Element, Binary. Node *lt, Binary. Node *rt ) : element( the. Element ), left( lt ), right( rt ) { } friend class Binary. Search. Tree<EType>; };

Binary. Search. Tree. h template <class EType> class Binary. Search. Tree { public: Binary.

Binary. Search. Tree. h template <class EType> class Binary. Search. Tree { public: Binary. Search. Tree( const EType& not. Found ); Binary. Search. Tree( const Binary. Search. Tree& rhs ); ~Binary. Search. Tree( ); const EType& find. Min( ) const; const EType& find. Max( ) const; const EType& find( const EType & x ) const; bool is. Empty( ) const; void print. Inorder( ) const;

Binary. Search. Tree. h void insert( const EType& x ); void remove( const EType&

Binary. Search. Tree. h void insert( const EType& x ); void remove( const EType& x ); const Binary. Search. Tree & operator= ( const Binary. Search. Tree & rhs );

Binary. Search. Tree. h private: Binary. Node<EType>* root; // ITEM_NOT_FOUND object used to signal

Binary. Search. Tree. h private: Binary. Node<EType>* root; // ITEM_NOT_FOUND object used to signal failed finds const EType ITEM_NOT_FOUND; const EType& element. At( Binary. Node<EType>* t ); void insert(const EType& x, Binary. Node<EType>* & t); void remove(const EType& x, Binary. Node<EType>* & t); Binary. Node<EType>* find. Min(Binary. Node<EType>* t); Binary. Node<EType>* find. Max(Binary. Node<EType>* t); Binary. Node<EType>* find(const EType& x, Binary. Node<EType>* t ); void make. Empty(Binary. Node<EType>* & t); void print. Inorder(Binary. Node<EType>* t); }; #endif