-
Notifications
You must be signed in to change notification settings - Fork 2
/
distance_k_target_node.cpp
157 lines (129 loc) · 3.58 KB
/
distance_k_target_node.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
/*
find all the nodes at a distance k from the given target node.
K distance can be in both the upward and downward and left and right sides.
we need to find out the ancestors of the target node.
nodes at a distance K - 2 - d(from the previous root node) in the other side of the tree
input: 1 2 4 6 -1 -1 7 10 -1 -1 11 -1 -1 5 8 -1 -1 9 -1 -1 3 -1 -1
*/
#include <iostream>
#include <queue>
using namespace std;
class node {
public:
int data;
node *left;
node *right;
node(int data) {
this->data = data;
left = right = NULL;
}
};
// preorder build of the tree
node* buildTree() {
int data;
cin >> data;
if(data == -1)
return NULL;
node *root = new node(data);
root->left = buildTree();
root->right = buildTree();
return root;
}
void BFS(node *root) {
if(root == NULL)
return;
queue<node*> q;
q.push(root);
// for the newline
q.push(NULL);
while(!q.empty()) {
node *front = q.front();
q.pop();
if(front == NULL) {
cout << endl;
if(!q.empty())
q.push(NULL);
}
else {
cout << front->data << " ";
// insert the children of front in the queue if they exist
if(front->left)
q.push(front->left);
if(front->right)
q.push(front->right);
}
}
}
// print the children at a distance from the target node, downside.
void printAtLevelK(node *root, int k) {
if(root == NULL)
return;
if(k == 0) {
cout << root->data << " ";
return;
}
printAtLevelK(root->left, k - 1);
printAtLevelK(root->right, k - 1);
return;
}
// main function to take into account ancestors
// from every node return the distance of the target node from that node
int printAtDistanceK(node *root, node *target, int k) {
// base case
if(root == NULL)
return -1;
// reach the target node
if(root == target) {
// print the children in the subtrees of this target node.
printAtLevelK(target, k);
return 0;
}
// traverse the ancestor nodes
int dist_left = printAtDistanceK(root->left, target, k);
// if target is present in the left subtree
if(dist_left != -1) {
/* now there are 2 cases:
1. print the ancestor
2. you need to go to the right subtree of the ancestor
*/
if(dist_left + 1 == k)
cout << root->data << " ";
else {
printAtLevelK(root->right, k - 2 - dist_left);
}
return 1 + dist_left;
}
int dist_right = printAtDistanceK(root->right, target, k);
// if target is present in the right subtree
if(dist_right != -1) {
if(dist_right + 1 == k)
cout << root->data << " ";
// go to the left subtree of the ancestor
else {
printAtLevelK(root->left, k - 2 - dist_right);
}
return 1 + dist_right;
}
// target node was not present in the left and right subtree of the given node.
return -1;
}
// operator overloading cin
istream& operator>>(istream &cin, node *&root) {
root = buildTree();
return cin;
}
// operator overloading cout
ostream& operator<<(ostream &cout, node *root) {
BFS(root);
return cout;
}
int main() {
node *root = NULL;
cin >> root;
node *target = root->left->left;
cout << root << endl;
int k;
cin >> k;
printAtDistanceK(root, target, k);
return 0;
}