-
Notifications
You must be signed in to change notification settings - Fork 0
/
bst.cpp
181 lines (158 loc) · 4.46 KB
/
bst.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* Code to learn how to build Binary Search Tree and associated funtions.
This topic seems to be a frequently occusrring theme in SW interviews;
Points to note: A binary tree is made of nodes, where each node contains a
"left" pointer, a "right" pointer, and a data element. The "root" pointer
points to the topmost node in the tree. The left and right pointers recursively
point to smaller "subtrees" on either side. A Binary Search Tree (BST) is a special
case of a Binary Tree, where nodes are sorted in some order, e.g., the top most
(root) node is the largest, the next smaller or qeual (<=) node gets added to the
left and the next larger node (>) (compared ot the root), gets added to the right,
and so forth recursively, until there are no more nodes.
BSTs are fast at insert and lookup, as they basically use a binary search to find
a node in O(log(N)) time.Thereforem BSTs are good for dictionary problems.
$Author$: Kalyan Subramanian
$emai$: kalyan dot sub at gmail
$Date$: Aug 21, 2014.
*/
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
/* Basic Binary Tree structure: the current node (parent) has a left child and
a right child node
*/
typedef struct Node Node;
typedef struct Node* NodePtr;
struct Node
{
int data;
NodePtr left;
NodePtr right;
};
//function prototypes:
NodePtr createNode(int data);
NodePtr insert(NodePtr node, int data);
NodePtr build123a();
int sizeOfTree( NodePtr node);
NodePtr build123b();
NodePtr build123c();
// Helper function that alloates and inserts a node in the BST
NodePtr createNode(int data)
{
NodePtr node = new(Node);
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
/*
Given a BST tree and a datum, inserts a new node
with the given datum in the correct place in the tree.
Returns the new root pointer which the caller should
then use...
*/
NodePtr insert(NodePtr node, int data)
{
if (node == NULL)
{
return (createNode(data));
}
else
{
if (data <= node->data) // lte case, go left
{
node->left = insert(node->left, data);
}
else// gt case, go right
{
node->right= insert(node->right, data);
}
}
return node;
}
NodePtr build123a()
{
NodePtr root = createNode(2);
NodePtr lChild = createNode(1);
NodePtr rChild = createNode(3);
root->left = lChild;
root->right = rChild;
return root;
}
NodePtr build123b()
{
NodePtr root = NULL;
root = createNode(2);
root->left = createNode(1);
root->right = createNode(3);
return root;
}
NodePtr build123c()
{
NodePtr root = NULL;
root = insert(root, 2);
root = insert(root, 1);
root = insert(root, 3);
return root;
}
/* Calculate the number of nodes in the tree */
int sizeOfTree( NodePtr node)
{
int numNodes;
if ( node == NULL )
{
numNodes = 0;
}
else
{
numNodes = sizeOfTree( node->left) + 1 + sizeOfTree( node-> right);
}
return numNodes;
}
/* Given a binary tree, find a datum: return true if the datum is foound in one of the
nodes of the tree; recusively traverse the nodes, choosing left or right by comparing the
sought for value to the current node:
*/
static int lookup(NodePtr startNode, int target)
{
cout << "lookup(): startNode->data = " << startNode->data << "\n";
// 1. base case: empty tree, so retrun false right away:
if (startNode == NULL)
{
return false;
}
else
{
if ( target == startNode->data ) // if we found it here, great !
{
cout << "lookup(): got it !\n";
return true;
}
if (target < startNode->data) // lte case, recurse left
{
cout << "lookup(): going left: target =" << target << "data = " << startNode->data << "\n";
return (lookup(startNode->left, target));
}
else // gt case, recurse right
{
cout << "lookup(): going right: target =" << target << "data = " << startNode->data << "\n";
return (lookup(startNode->right, target));
}
}
}
int main(int argc, char* argv[])
{
NodePtr aNode = build123a();
int target = 3;
int size = sizeOfTree(aNode);
cout << "size of tree so far is " << size << "\n";
if (lookup(aNode, 3))
{
cout << "Found " << target << "\n";
}
else
{
cout << "Could not find " << target << "\n";
}
return 0;
}