-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTrie.cpp
178 lines (148 loc) · 3.92 KB
/
Trie.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
#include "Trie.h"
/*Wrapper function to check the given Bnode is last LeafNode or Not */
bool isLeafNode(BNode *p) {
if(p == NULL) return false;
if((p->l == NULL)&& (p->r == NULL))
return true;
return false;
}
Trie :: Trie() {
head = NULL;
}
/*
Parameter : Ip address of the destination vertex . Next Vertex present in the shortest path to reach that destination .
This function insert the ip value ,next hop value pair in the binary trie
*/
void Trie :: InsertPair(string Ip, int nextHop) {
if(head == NULL) {
head = new TNode(Ip, nextHop);
return;
}
BNode *TPtr = head;
BNode *Parent = NULL;
int currLevel = 0; //This is the current branch level
int dBit; //This is the branch at which node bit value differes
while (1) {
if(TPtr == NULL) {
if(Ip[currLevel-1] == '0') {
Parent->l = new TNode(Ip, nextHop);
} else {
Parent->r = new TNode(Ip, nextHop);
}
break;
}
if(TPtr->l == NULL && TPtr->r == NULL) { //This is the case when we arrived at Leaf Node
string trieIp = ((TNode *)TPtr)->key;
for(int ii = 0; ii < Ip.size(); ii++) {
if(trieIp[ii] != Ip[ii]) {
dBit = ii;
break;
}
}
if(dBit == Ip.size()) { //If the IP is already present we dont need to add anything
return;
}
if(Parent == NULL) {
head = new BNode();
Parent = head;
} else {
if(Ip[currLevel-1] == '0') {
Parent->l = new BNode(); //If the last level bit value is 0 then we need to go left in the trie
Parent = Parent->l;
} else {
Parent->r = new BNode();
Parent = Parent->r;//If the last level bit value is 1 then we need to go right in the trie
}
}
for(int ii = currLevel; ii < dBit; ii++) {
if(Ip[ii] == '0') {
Parent->l = new BNode();
Parent = Parent->l;
} else {
Parent->r = new BNode();
Parent = Parent->r;
}
}
if(Ip[dBit] == '0') {
Parent->l = new TNode(Ip, nextHop);
Parent->r = TPtr;
} else {
Parent->r = new TNode(Ip, nextHop);
Parent->l = TPtr;
}
break;
}
if(Ip[currLevel] == '0') {
Parent = TPtr;
TPtr = TPtr->l;
currLevel++;
} else {
Parent = TPtr;
TPtr = TPtr->r;
currLevel++;
}
}
}
/*
Parameter :Ip address of the destination node which is to be searched in the Trie
This function searches the input Ip in the corresponding trie and update the longest matched prefix IP in the TrieResult
*/
TrieResult Trie :: Search(string destIp) {
TrieResult res;
string prefixIp = "";
BNode *tPtr = head;
int currLevel = 0;
while(1) {
if(tPtr == NULL) break;
if(isLeafNode(tPtr)) {
res.IpPrefix = prefixIp;
res.nextHop = ((TNode *)tPtr)->data;
break;
}
if(destIp[currLevel] == '0') { //When the current level bit is 0 then we add 0 bit in the prefix result
prefixIp += '0';
tPtr = tPtr->l;
currLevel++;
} else {
prefixIp += '1'; //When the current level bit is 1 then we add 1 1 in the prefix result
tPtr = tPtr->r;
currLevel++;
}
}
return res;
}
void Trie :: OptimizePath() {
head = Optimize(head);
}
/*
Parameter :Takes BNode pointer as an argument .For the first call the BNode is the head pointer of the corresponding Trie .This function optimizes the trie based on post order traversal of the Trie .It removes the subTries whose Next Hop is same for all destination .
*/
BNode* Trie :: Optimize(BNode* root) {
if(root == NULL) return NULL;
if(root->l == NULL && root->r == NULL) {
return root;
}
BNode *l = Optimize(root->l);
BNode *r = Optimize(root->r);
if(l == NULL || r== NULL) {
if(l == NULL) {
if(isLeafNode(r)) {
return r;
}
} else {
if(isLeafNode(l)) {
return l;
}
}
}
if(isLeafNode(l) && isLeafNode(r)) {
int leftData = ((TNode*)l)->data;
int rightData = ((TNode*)r)->data;
if(leftData == rightData) { //When we arrived at tha Leaf Node and both the leaf nodes have same Neaxt Hop then we do trie shrinking
return r;
}
}
root->l = l;
root->r = r;
return root;
}