Binary Search Tree (BST) Implementation C++

//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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值