//Implement the BST data structure, and the related traverse, insert, delete operations.
#include <iostream>
using namespace std;
//note: NULL must be upper case
typedef int elem_t; //elem_t is hidden from client
struct Vertex
{
Vertex *Left;
elem_t Elem;
Vertex *Right;
};
class BST
{
private:
Vertex *Root;
public:
// constructor initializes Root
BST()
{
Root = NULL; // This is an empty tree
}
// destructor must completely destroy the tree
~BST()
{
_dtraverse(Root); // traverse to delete all vertices in post order
Root = NULL;
}
// PURPOSE: Does Post Order traversal of the tree and deletes each vertex
// PARAM: pointer to the vertex to be deleted
void _dtraverse(Vertex *V)
{
if (V != NULL)
{
_dtraverse(V->Left);
_dtraverse(V->Right);
}
}
// PURPOSE: Show elements in IN order traversal from the Root
void ShowInOrder()
{
cout << "Elements in the IN order: " << endl;
_inOrderTraverse(Root);
}
// PURPOSE: Does IN order traversal from V recursively
// PARAM: pointer to the vertex to visit right now
void _inOrderTraverse(Vertex *V)
{
if (V != NULL)
{
_inOrderTraverse(V->Left);
cout<< V->Elem <<endl;
_inOrderTraverse(V->Right);
}
}
// PURPOSE: Adds a vertex to the binary search tree for new element
// PARAM: the new element E
// ALGORITHM: We will do this iteratively (not recursively)
// - smaller than the current -> go to the left
// - bigger than the current -> go to the right
// - cannot go any further -> add it there
void InsertVertex(elem_t E)
{
Vertex *N; // N will point to the new vertex to be inserted
N = new Vertex; // a new vertex is created
N->Left = NULL; // make sure it does not
N->Right = NULL; // point to anything
N->Elem = E; // put element E in it
if ( Root == NULL)
{
Root = N;
cout << "...adding " << E << " as the root" << endl;
}
else // the tree is not empty
{
Vertex *V; // V will point to the current vertex
Vertex *Parent; // Parent will point to V's parents
V = Root; // start with the root as V
while (V != NULL) // go down the tree until you cannot go any further
{
if (N->Elem == V->Elem) // special case
{
cout << "...error: the element already exists" << endl;
return;
}
else if (N->Elem < V->Elem) // what I have is smaller than V
{
cout << "...going to the left" << endl;
Parent=V; // ** change Parent to be V to go down
V=V->Left; // ** change V to be V's Left
}
else // what I have is bigger than V
{
cout << "...going to the right" << endl;
Parent=V;// ** change Parent to be V to go down
V=V->Right;// ** change V to be V's Right
}
}//end of while
// reached NULL -- Must add N as the Parent's child
if (N->Elem < Parent->Elem)
{
Parent->Left=N; // ** Parent's Left should point to the same place as N
cout << "...adding " << E << " as the left child of " << Parent->Elem << endl;
}
else
{
Parent->Right=N;// ** Parent's Right should point to the same place as N
cout << "...adding " << E << " as the right child of "<< Parent->Elem << endl;
}
}// end of normal case
}
// PURPOSE: Adds a vertex to the binary search tree for new element recursively
void InsertVertex_Recursive(elem_t E)
{
Vertex *N; // N will point to the new vertex to be inserted
N = new Vertex; // a new vertex is created
N->Left = NULL; // make sure it does not
N->Right = NULL; // point to anything
N->Elem = E; // put element E in it
if( Root == NULL)
{
Root = N;
cout << "...adding " << E << " as the root" << endl;
}
else
{
_insertHelper(Root, E);
}
}
void _insertHelper(Vertex *V, elem_t E)
{
Vertex *N = new Vertex;
N->Left = NULL;
N->Right = NULL;
N->Elem = E;
if (E == V->Elem) // special case
{
cout << "...error: the element already exists" << endl;
return;
}
else if(E < V->Elem )
{
if( V->Left == NULL)
{
V->Left = N;
}
else
{
_insertHelper( V->Left, E);
}
}
else
{
if( V->Right == NULL)
{
V->Right = N;
}
else
{
_insertHelper( V->Right, E);
}
}
}
// PURPOSE: Deletes a vertex that has E as its element.
// PARAM: element E to be removed
// ALGORITHM: First we must find the vertex then call Remove
void DeleteVertex(elem_t E)
{
cout << "Trying to delete " << E << endl;
Vertex *V; // the current vertex
Vertex *Parent = NULL; // its parent
if ((E == Root->Elem) && (Root->Left == NULL) && (Root->Right == NULL))
{
cout << "...deleting the lonely root" << endl;
delete Root;
Root = NULL;
return;
} // only the Root was there and deleted it
V = Root; // start with the root to look for E
while(V != NULL)
{
if( E == V->Elem)
{
cout << "...removing" << V-> Elem <<endl;
_delete(V, Parent);
return;
}
else if( E < V-> Elem)
{
cout << "...going to the left" << endl;
Parent=V;
V=V->Left;// ** update Parent and V here to go down
}
else
{
cout << "...going to the right" << endl;
Parent=V;
V=V->Right;// ** update Parent and V here to go down
}
}// end of while
// reached NULL -- did not find it
cout << "Did not find the key in the tree." << endl;
}
// PURPOSE: Removes vertex pointed to by V
// PARAM: V and its parent pointer P
// Case 1: it is a leaf – delete it
// Case 2: it has just one child – bypass it
// Case 3: it has two children – replace it with the max of the left //subtree
void _delete(Vertex *V, Vertex *P)
{
if (V->Left==NULL && V->Right==NULL)// ** if V is a leaf (case 1)
{
cout << ".. removing a leaf" << endl;
if (V==P->Left)// ** if V is a left child of P
{
delete V; // ** delete V and also make Parent's left NULL
P->Left=NULL;
}
else // V is a right child of the Parent
{
delete V;// ** delete V and also make Parent's right NULL
P->Right=NULL;
}
}
else if (V->Left!=NULL && V->Right==NULL)// ** else if V has just the left child (case 2)
{
cout << "removing a vertex with just the left child" << endl;
if (P->Right==V)
{
P->Right=V->Left;
delete V;
}
if (P->Left==V)
{
P->Left=V->Left; // ** Make Parent’left or right point to the left child and delete V (You need if then else to determine left or right)
delete V;
}
}
else if (V->Left==NULL && V->Right!=NULL)// **else if V has just the right child
{
cout << "removing a vertex with just the right child" << endl;
if (P->Right==V)
{
P->Right=V->Right;
delete V;
}
if (P->Left==V)
{
P->Left=V->Right; // ** Make Parent' left or right point to the right child and delete V (need if then else to determine left or right)
delete V;
}
}
else // V has two children (case 3)
{
cout << "...removing an internal vertex with children" << endl;
cout << ".....find the MAX of its left sub-tree" << endl;
elem_t Melem;
Melem = findMax(V); // find MAX element in the left sub-tree of V
cout << ".....replacing " << V->Elem << " with " << Melem << endl;
V->Elem = Melem;// ** Replace V's element with Melem here
}
}
// PURPOSE: Finds the Maximum element in the left sub-tree of V
elem_t findMax(Vertex *V)
{
Vertex *Parent = V;
V = V->Left; // start with the left child of V
while (V->Right!=NULL) // ** while the right child of V is still available
{
Parent=V;
V=V->Right;// ** update Parent and V to go to the right
}
// reached NULL Right -- V now has the MAX element
elem_t X = V->Elem;
cout << ".....Max is " << X << endl;
_delete(V, Parent); // remove the MAX vertex
return X; // return the MAX element
}// end of FindMax
};
int main()
{
BST MyTree; // my first binary search tree
for(int i = 1; i <=9 ; i=i+2) // inserting 1,3,5,7,9 into the tree
MyTree.InsertVertex(i);
//MyTree.InsertVertex_Recursive(2);
for(int i = 10; i >=2 ; i=i-2) // inserting 10,8,6,4,2 into the tree
MyTree.InsertVertex(i);
MyTree.ShowInOrder(); // should show in the sorted order
//********************************************************
cout << "=== Starting a new tree with 7 nodes ===="<< endl;
BST Nums; // Nums is the second binary search tree
// creates a shallowest 7 node tree (draw this)
Nums.InsertVertex(3); // root
Nums.InsertVertex(1); // level 1 L
Nums.InsertVertex(2); // level 2 R
Nums.InsertVertex(0); // level 2 L
Nums.InsertVertex(5); // level 1 R
Nums.InsertVertex(6); // level 2 R
Nums.InsertVertex(4); // level 2 L
Nums.InsertVertex(4); // should be an error
//and show the nodes in sorted order
Nums.ShowInOrder();
//and then delete some nodes
// - level 2 right most leaf
Nums.DeleteVertex(6);
// - level 1 right mode node with one left child
Nums.DeleteVertex(5);
// - level 0 root with two children
Nums.DeleteVertex(3);
// - deleting a non-existing one
Nums.DeleteVertex(7);
//and then show the remaining nodes in sorted order
Nums.ShowInOrder();
//********************************************************
//Root has left child
//Root has right child
//Root has both children
cout << "=== Starting a new tree with 7 nodes ===="<< endl;
BST newTest; // newTest is the third binary search tree
// creates a new 8 node tree (draw this)
newTest.InsertVertex(7); // root
newTest.InsertVertex(1); // level 1 L
newTest.InsertVertex(2); // level 2 R
newTest.InsertVertex(0); // level 2 L
newTest.InsertVertex(5); // level 3 R
newTest.InsertVertex(6); //level 4 R
newTest.InsertVertex(9); // level 2 R
newTest.InsertVertex(4); // level 4 L
newTest.InsertVertex(10); // level 3 R
newTest.InsertVertex(8); //level 3 L
//and show the nodes in sorted order
newTest.ShowInOrder();
newTest.DeleteVertex(7);
newTest.ShowInOrder();
newTest.DeleteVertex(6);
newTest.ShowInOrder();
newTest.DeleteVertex(5);
newTest.ShowInOrder();
newTest.DeleteVertex(4);
newTest.ShowInOrder();
newTest.DeleteVertex(3);
newTest.ShowInOrder();
newTest.DeleteVertex(1);
newTest.ShowInOrder();
system("pause");
return 0;
}
Binary Search Tree (BST) Implementation C++
最新推荐文章于 2021-09-21 10:13:07 发布