Skip to content

Commit c71ca3a

Browse files
committed
day5 -some bst operations
1 parent 4b5b8e2 commit c71ca3a

File tree

3 files changed

+331
-249
lines changed

3 files changed

+331
-249
lines changed

include/binarySearchTree.h

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
#ifndef BINARY_SEARCH_TREE_H
2+
#define BINARY_SEARCH_TREE_H
3+
4+
#include <iostream>
5+
#include <stdexcept>
6+
#include <generic.h>
7+
#include <iomanip>
8+
9+
namespace algo {
10+
template <typename Comparable>
11+
class BinarySearchTree {
12+
public:
13+
14+
// default constructor
15+
BinarySearchTree( ) : root{ nullptr }
16+
{ }
17+
18+
// copy constructor
19+
BinarySearchTree( const BinarySearchTree & rhs )
20+
: root { nullptr }
21+
{
22+
root = __copy( rhs.root );
23+
}
24+
25+
// move constructor
26+
BinarySearchTree( BinarySearchTree && rhs )
27+
: root { rhs.root }
28+
{
29+
rhs.root = nullptr;
30+
}
31+
32+
// copy assignment
33+
BinarySearchTree & operator= ( const BinarySearchTree & rhs )
34+
{
35+
BinarySearchTree copy = rhs;
36+
algo::swap( *this, copy );
37+
return *this;
38+
}
39+
40+
// move assignment
41+
BinarySearchTree & operator= ( BinarySearchTree && rhs )
42+
{
43+
algo::swap( root, rhs.root );
44+
return *this;
45+
}
46+
47+
// destructor
48+
~BinarySearchTree( )
49+
{
50+
clear();
51+
}
52+
53+
// Smallest item in Tree
54+
const Comparable & findMin() const
55+
{
56+
if ( empty() )
57+
throw std::underflow_error("Empty Tree");
58+
return __findMin( root )->element;
59+
}
60+
61+
// Largest item in Tree
62+
const Comparable & findMax() const
63+
{
64+
if ( empty() )
65+
throw std::underflow_error("Empty Tree");
66+
return __findMax( root )->element;
67+
}
68+
69+
// does tree contain obj
70+
bool contains( const Comparable & obj ) const
71+
{
72+
return __contains( root, obj );
73+
}
74+
75+
// isTreeEmpty
76+
bool empty( ) const
77+
{
78+
return ( root == nullptr );
79+
}
80+
81+
// print the content of tree in sorted order
82+
void printTree(std::ostream & out = std::cout) const
83+
{
84+
if ( empty( ) ) {
85+
std::cout << "Empty Tree\n";
86+
} else {
87+
__printTree( root, out );
88+
}
89+
}
90+
91+
// clear the tree
92+
void clear() const
93+
{
94+
__clear( root );
95+
}
96+
97+
// insert element to tree, duplicates ignored
98+
void insert( const Comparable & obj )
99+
{
100+
__insert( root, obj );
101+
}
102+
103+
// move insert element to tree, duplicates ignored
104+
void insert( Comparable && obj )
105+
{
106+
__insert( root, std::move( obj ) );
107+
}
108+
109+
// remove element from tree
110+
void remove( const Comparable & obj )
111+
{
112+
__remove( root, obj );
113+
}
114+
115+
void prettyPrintTree( ) {
116+
__prettyPrintTree(root);
117+
}
118+
119+
private:
120+
struct BinaryNode {
121+
Comparable element;
122+
BinaryNode *left;
123+
BinaryNode *right;
124+
125+
BinaryNode( const Comparable & obj = Comparable(),
126+
BinaryNode *lptr = nullptr,
127+
BinaryNode *rptr = nullptr )
128+
: element{ obj }, left { lptr }, right { rptr }
129+
{ }
130+
131+
BinaryNode( Comparable && obj, BinaryNode *lptr,
132+
BinaryNode *rptr )
133+
: element{ std::move(obj) }, left{ lptr }, right{ rptr }
134+
{ }
135+
}; // end of struct BinaryNode
136+
137+
BinaryNode *root;
138+
139+
const Comparable & __findMin( BinaryNode *node ) const
140+
{
141+
if ( node == nullptr )
142+
return nullptr;
143+
else if ( node->left == nullptr )
144+
return node;
145+
else
146+
return __findMin( node->left );
147+
}
148+
149+
const Comparable & __findMax( BinaryNode *node ) const
150+
{
151+
if ( node == nullptr )
152+
return nullptr;
153+
else if ( node->right == nullptr )
154+
return node;
155+
else
156+
return __findMax( node->right );
157+
}
158+
159+
bool __contains( BinaryNode *node, const Comparable & obj ) const
160+
{
161+
if ( node == nullptr )
162+
return false;
163+
else if ( obj < node->element )
164+
return __contains( node->left, obj );
165+
else if ( obj > node->element )
166+
return __contains( node->right, obj );
167+
else
168+
return true;
169+
}
170+
171+
void __insert( BinaryNode * & node, const Comparable & obj )
172+
{
173+
if ( node == nullptr ) {
174+
node = new BinaryNode( obj, nullptr, nullptr );
175+
} else if ( obj < node->element ) {
176+
__insert( node->left, obj );
177+
} else if ( obj > node->element ) {
178+
__insert( node->right, obj );
179+
} else {
180+
//ignore case of duplicate
181+
}
182+
}
183+
184+
void __insert( BinaryNode * & node, Comparable && obj )
185+
{
186+
if ( node == nullptr ) {
187+
node = new BinaryNode( std::move( obj ), nullptr, nullptr );
188+
return;
189+
}
190+
BinaryNode * currNode = node;
191+
bool flag = true;
192+
while (flag) {
193+
if ( currNode->element > obj ) {
194+
if ( currNode->left == nullptr ) {
195+
currNode->left = new BinaryNode( std::move( obj ), nullptr, nullptr );
196+
flag = false;
197+
} else {
198+
currNode = currNode->left;
199+
}
200+
} else if (currNode->element < obj ) {
201+
if (currNode->right == nullptr) {
202+
currNode->right = new BinaryNode( std::move( obj ), nullptr, nullptr );
203+
flag = false;
204+
} else {
205+
currNode = currNode->right;
206+
}
207+
} else {
208+
flag = false;
209+
//case of duplicate
210+
}
211+
}
212+
}
213+
214+
void __remove( BinaryNode *node, const Comparable & obj ) {
215+
if ( node == nullptr ) {
216+
return;
217+
}
218+
219+
if ( obj < node->element ) {
220+
__remove( node->left, obj );
221+
} else if ( obj > node->element ) {
222+
__remove( node->right, obj );
223+
} else {
224+
if ( node->left != nullptr &&
225+
node->right != nullptr ) {
226+
node->element = __findMin(node->right)->element;
227+
__remove( node->right, node->element);
228+
} else {
229+
BinaryNode *oldNode = node;
230+
node = ( node->left != nullptr ) ? node->left : node->right;
231+
delete oldNode;
232+
}
233+
234+
}
235+
}
236+
237+
void __clear( BinaryNode *node ) const
238+
{
239+
if ( node != nullptr ) {
240+
__clear( node->left );
241+
__clear( node->right );
242+
delete node;
243+
}
244+
}
245+
246+
void __printTree( BinaryNode *node, std::ostream& out ) const
247+
{
248+
if ( node != nullptr ) {
249+
__printTree( node->left, out );
250+
out << node->element << " ";
251+
__printTree( node->right, out );
252+
}
253+
}
254+
255+
BinaryNode* __copy( BinaryNode *node ) {
256+
if ( node == nullptr ) {
257+
return nullptr;
258+
}
259+
return new BinaryNode( node->element,
260+
__copy( node->left ),
261+
__copy( node->right) );
262+
}
263+
264+
//pretty print post order
265+
void __prettyPrintTree( BinaryNode *node, int indent = 0, std::ostream & out = std::cout)
266+
{
267+
if ( node != nullptr ) {
268+
if ( node->right != nullptr )
269+
__prettyPrintTree( node->right, indent + 4, out);
270+
271+
if ( indent )
272+
out << std::setw(indent) << ' ';
273+
274+
if ( node->right != nullptr )
275+
out<<" /\n" << std::setw(indent) << ' ';
276+
277+
out << node->element << std::endl;
278+
279+
if ( node->left != nullptr ) {
280+
out << std::setw(indent) << ' ' <<" \\\n";
281+
__prettyPrintTree( node->left, indent + 4, out);
282+
}
283+
}
284+
}
285+
286+
}; // end of class BinarySearchTree
287+
} // end of namespace algo
288+
289+
#endif

0 commit comments

Comments
 (0)