-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
in-order-predecessor-and-successor.cpp
194 lines (167 loc) · 5.44 KB
/
in-order-predecessor-and-successor.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
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <iostream>
struct TreeNode{
TreeNode* left;
TreeNode* right;
int data;
TreeNode(const int& data): data(data), left(nullptr), right(nullptr){}
};
TreeNode* find(TreeNode* root, const int& data){
/**
* Find the node that contains the given data and
* return that node
*
* @params: `root` root/parent node of the tree
* @params: `data` data to be find in the tree
* @return: tree node that contains the data
*
* Average case Time Complexity: O(log(n))
* Worst case Time Complexity: O(n)
*
*/
if(root == nullptr) { throw std::runtime_error("Error: find() cannot find the data. The data doesn't exist."); }
else if(root->data == data) { return root; }
else if(root->data < data) { return find(root->right, data); }
else { return find(root->left, data); }
}
void Insert(TreeNode*& root, const int& data){
/**
* Create and Insert the node in the appropriate place of the tree
*
* @params: `root` root/parent node of the tree
* @params: `data` data to be inserted in the tree
* @return: void
*
* Average case Time Complexity: O(log(n))
* Worst case Time Complexity: O(n)
*
*/
if(root == nullptr) { root = new TreeNode(data); }
else if(root->data == data) { throw std::runtime_error("The node already exist. Duplicates not allowed"); }
else if(root->data < data) { Insert(root->right, data); }
else { Insert(root->left, data); }
}
TreeNode* rightmost(TreeNode* node){
/**
* Find and return the rightmost value of the sub-tree
*
* @params: `root` root/parent node of the tree
*
* @return: value of the node at the rightmost end of the sub tree
*/
if(node->right == nullptr){ return node; }
return rightmost(node->right);
}
TreeNode* predecessor(TreeNode* node, const int& data, TreeNode* value){
/**
* Find and return the previous smallest value to data
*
* @params: `node` root/parent node of the tree
* @params: `data` data to compare with
* @params: `value` holds the previous smaller value to data
*
* @return: previous smallest value to data
*/
if(node->data < data){ return predecessor(node->right, data, node); }
else if(node->data > data){ return predecessor(node->left, data, value); }
return value;
}
TreeNode* in_order_predecessor(TreeNode* root, const int& data){
/**
* Find the in-order predecessor of the given data
*
* @params: `root` root of the tree
* @params: `data` data where it's predecessor to be found
*
* @return: in-order predecessor for the given data
*/
TreeNode* node = find(root, data);
if(node->left !=nullptr){ return rightmost(node->left); }
return predecessor(root, data, nullptr);
}
TreeNode* leftmost(TreeNode* node){
/**
* Find and return the leftmost value of the sub-tree
*
* @params: `root` root/parent node of the tree
*
* @return: value of the node at the leftmost end of the sub tree
*/
if(node->left == nullptr){ return node; }
return leftmost(node->left);
}
TreeNode* successor(TreeNode* node, const int& data, TreeNode* value){
/**
* Find and return the next biggest value to data
*
* @params: `root` root/parent node of the tree
* @params: `data` data to compare with
* @params: `value` holds the next biggest value to data
*
* @return: previous smaller value to data
*/
if(node->data < data){ return successor(node->right, data, value); }
else if(node->data > data){ return successor(node->left, data, node); }
return value;
}
TreeNode* in_order_successor(TreeNode* root, const int& data){
/**
* Find the in-order successor of the given data
*
* @params: `data` data where it's predecessor to be found
* @params: `root` root of the tree for the prevSmallerAncester function
*
* @return: in-order successor for the given data
*/
TreeNode* node = find(root, data);
if(node->right !=nullptr){ return leftmost(node->right); }
return successor(root, data, nullptr);
}
void print(TreeNode* root){
/**
* Print the tree in an inorder fashion
*
* @params: `root` root/parent node of the tree
* @return: void
*/
if(root != nullptr){
print(root->left);
std::cout << root->data << " ";
print(root->right);
}
}
int main(){
TreeNode* root = nullptr;
Insert(root, 37);
Insert(root, 19);
Insert(root, 4);
Insert(root, 22);
Insert(root, 51);
Insert(root, 55);
Insert(root, 42);
Insert(root, 20);
Insert(root, 11);
Insert(root, 0);
print(root);
/*
Tree structure
37
/ \
19 51
/ \ / \
4 22 42 55
/\ /
0 11 20
OUTPUT:
0 4 11 19 20 22 37 42 51 55
*/
int value = 4;
if(in_order_predecessor(root, value)){
std::cout << "\nPredecessor of " << value << " is " << in_order_predecessor(root, value)->data << std::endl;
}
else{ std::cout << "\nNo predecessor" << std::endl; }
if(in_order_successor(root, value)){
std::cout << "Successor of " << value << " is " << in_order_successor(root, value)->data << std::endl;
}
else{ std::cout << "No successor" << std::endl; }
return 0;
}