1+ // Splay tree implementation in C++
2+ // Author: Algorithm Tutor
3+ // Tutorial URL: http://algorithmtutor.com/Data-Structures/Tree/Splay-Trees/
4+
5+ #include < iostream>
6+
7+ using namespace std ;
8+
9+ // data structure that represents a node in the tree
10+ struct Node {
11+ int data; // holds the key
12+ Node *parent; // pointer to the parent
13+ Node *left; // pointer to left child
14+ Node *right; // pointer to right child
15+ };
16+
17+ typedef Node *NodePtr;
18+
19+ // class SplayTree implements the operations in Splay tree
20+ class SplayTree {
21+ private:
22+ NodePtr root;
23+
24+ void preOrderHelper (NodePtr node) {
25+ if (node != nullptr ) {
26+ cout<<node->data <<" " ;
27+ preOrderHelper (node->left );
28+ preOrderHelper (node->right );
29+ }
30+ }
31+
32+ void inOrderHelper (NodePtr node) {
33+ if (node != nullptr ) {
34+ inOrderHelper (node->left );
35+ cout<<node->data <<" " ;
36+ inOrderHelper (node->right );
37+ }
38+ }
39+
40+ void postOrderHelper (NodePtr node) {
41+ if (node != nullptr ) {
42+ postOrderHelper (node->left );
43+ postOrderHelper (node->right );
44+ cout<<node->data <<" " ;
45+ }
46+ }
47+
48+ NodePtr searchTreeHelper (NodePtr node, int key) {
49+ if (node == nullptr || key == node->data ) {
50+ return node;
51+ }
52+
53+ if (key < node->data ) {
54+ return searchTreeHelper (node->left , key);
55+ }
56+ return searchTreeHelper (node->right , key);
57+ }
58+
59+ void deleteNodeHelper (NodePtr node, int key) {
60+ NodePtr x = nullptr ;
61+ NodePtr t, s;
62+ while (node != nullptr ){
63+ if (node->data == key) {
64+ x = node;
65+ }
66+
67+ if (node->data <= key) {
68+ node = node->right ;
69+ } else {
70+ node = node->left ;
71+ }
72+ }
73+
74+ if (x == nullptr ) {
75+ cout<<" Couldn't find key in the tree" <<endl;
76+ return ;
77+ }
78+ split (x, s, t); // split the tree
79+ if (s->left ){ // remove x
80+ s->left ->parent = nullptr ;
81+ }
82+ root = join (s->left , t);
83+ delete (s);
84+ s = nullptr ;
85+ }
86+
87+ void printHelper (NodePtr root, string indent, bool last) {
88+ // print the tree structure on the screen
89+ if (root != nullptr ) {
90+ cout<<indent;
91+ if (last) {
92+ cout<<" └────" ;
93+ indent += " " ;
94+ } else {
95+ cout<<" ├────" ;
96+ indent += " | " ;
97+ }
98+
99+ cout<<root->data <<endl;
100+
101+ printHelper (root->left , indent, false );
102+ printHelper (root->right , indent, true );
103+ }
104+ }
105+
106+ // rotate left at node x
107+ void leftRotate (NodePtr x) {
108+ NodePtr y = x->right ;
109+ x->right = y->left ;
110+ if (y->left != nullptr ) {
111+ y->left ->parent = x;
112+ }
113+ y->parent = x->parent ;
114+ if (x->parent == nullptr ) {
115+ this ->root = y;
116+ } else if (x == x->parent ->left ) {
117+ x->parent ->left = y;
118+ } else {
119+ x->parent ->right = y;
120+ }
121+ y->left = x;
122+ x->parent = y;
123+ }
124+
125+ // rotate right at node x
126+ void rightRotate (NodePtr x) {
127+ NodePtr y = x->left ;
128+ x->left = y->right ;
129+ if (y->right != nullptr ) {
130+ y->right ->parent = x;
131+ }
132+ y->parent = x->parent ;
133+ if (x->parent == nullptr ) {
134+ this ->root = y;
135+ } else if (x == x->parent ->right ) {
136+ x->parent ->right = y;
137+ } else {
138+ x->parent ->left = y;
139+ }
140+ y->right = x;
141+ x->parent = y;
142+ }
143+
144+ // splaying
145+ void splay (NodePtr x) {
146+ while (x->parent ) {
147+ if (!x->parent ->parent ) {
148+ if (x == x->parent ->left ) {
149+ // zig rotation
150+ rightRotate (x->parent );
151+ } else {
152+ // zag rotation
153+ leftRotate (x->parent );
154+ }
155+ } else if (x == x->parent ->left && x->parent == x->parent ->parent ->left ) {
156+ // zig-zig rotation
157+ rightRotate (x->parent ->parent );
158+ rightRotate (x->parent );
159+ } else if (x == x->parent ->right && x->parent == x->parent ->parent ->right ) {
160+ // zag-zag rotation
161+ leftRotate (x->parent ->parent );
162+ leftRotate (x->parent );
163+ } else if (x == x->parent ->right && x->parent == x->parent ->parent ->left ) {
164+ // zig-zag rotation
165+ leftRotate (x->parent );
166+ rightRotate (x->parent );
167+ } else {
168+ // zag-zig rotation
169+ rightRotate (x->parent );
170+ leftRotate (x->parent );
171+ }
172+ }
173+ }
174+
175+ // joins two trees s and t
176+ NodePtr join (NodePtr s, NodePtr t){
177+ if (!s) {
178+ return t;
179+ }
180+
181+ if (!t) {
182+ return s;
183+ }
184+ NodePtr x = maximum (s);
185+ splay (x);
186+ x->right = t;
187+ t->parent = x;
188+ return x;
189+ }
190+
191+ // splits the tree into s and t
192+ void split (NodePtr &x, NodePtr &s, NodePtr &t) {
193+ splay (x);
194+ if (x->right ) {
195+ t = x->right ;
196+ t->parent = nullptr ;
197+ } else {
198+ t = nullptr ;
199+ }
200+ s = x;
201+ s->right = nullptr ;
202+ x = nullptr ;
203+ }
204+
205+ public:
206+ SplayTree () {
207+ root = nullptr ;
208+ }
209+
210+ // Pre-Order traversal
211+ // Node->Left Subtree->Right Subtree
212+ void preorder () {
213+ preOrderHelper (this ->root );
214+ }
215+
216+ // In-Order traversal
217+ // Left Subtree -> Node -> Right Subtree
218+ void inorder () {
219+ inOrderHelper (this ->root );
220+ }
221+
222+ // Post-Order traversal
223+ // Left Subtree -> Right Subtree -> Node
224+ void postorder () {
225+ postOrderHelper (this ->root );
226+ }
227+
228+ // search the tree for the key k
229+ // and return the corresponding node
230+ NodePtr searchTree (int k) {
231+ NodePtr x = searchTreeHelper (this ->root , k);
232+ if (x) {
233+ splay (x);
234+ }
235+ return x;
236+ }
237+
238+ // find the node with the minimum key
239+ NodePtr minimum (NodePtr node) {
240+ while (node->left != nullptr ) {
241+ node = node->left ;
242+ }
243+ return node;
244+ }
245+
246+ // find the node with the maximum key
247+ NodePtr maximum (NodePtr node) {
248+ while (node->right != nullptr ) {
249+ node = node->right ;
250+ }
251+ return node;
252+ }
253+
254+ // find the successor of a given node
255+ NodePtr successor (NodePtr x) {
256+ // if the right subtree is not null,
257+ // the successor is the leftmost node in the
258+ // right subtree
259+ if (x->right != nullptr ) {
260+ return minimum (x->right );
261+ }
262+
263+ // else it is the lowest ancestor of x whose
264+ // left child is also an ancestor of x.
265+ NodePtr y = x->parent ;
266+ while (y != nullptr && x == y->right ) {
267+ x = y;
268+ y = y->parent ;
269+ }
270+ return y;
271+ }
272+
273+ // find the predecessor of a given node
274+ NodePtr predecessor (NodePtr x) {
275+ // if the left subtree is not null,
276+ // the predecessor is the rightmost node in the
277+ // left subtree
278+ if (x->left != nullptr ) {
279+ return maximum (x->left );
280+ }
281+
282+ NodePtr y = x->parent ;
283+ while (y != nullptr && x == y->left ) {
284+ x = y;
285+ y = y->parent ;
286+ }
287+
288+ return y;
289+ }
290+
291+ // insert the key to the tree in its appropriate position
292+ void insert (int key) {
293+ // normal BST insert
294+ NodePtr node = new Node;
295+ node->parent = nullptr ;
296+ node->left = nullptr ;
297+ node->right = nullptr ;
298+ node->data = key;
299+ NodePtr y = nullptr ;
300+ NodePtr x = this ->root ;
301+
302+ while (x != nullptr ) {
303+ y = x;
304+ if (node->data < x->data ) {
305+ x = x->left ;
306+ } else {
307+ x = x->right ;
308+ }
309+ }
310+
311+ // y is parent of x
312+ node->parent = y;
313+ if (y == nullptr ) {
314+ root = node;
315+ } else if (node->data < y->data ) {
316+ y->left = node;
317+ } else {
318+ y->right = node;
319+ }
320+
321+ // splay the node
322+ splay (node);
323+ }
324+
325+ NodePtr getRoot (){
326+ return this ->root ;
327+ }
328+
329+ // delete the node from the tree
330+ void deleteNode (int data) {
331+ deleteNodeHelper (this ->root , data);
332+ }
333+
334+ // print the tree structure on the screen
335+ void prettyPrint () {
336+ printHelper (this ->root , " " , true );
337+ }
338+
339+ };
340+
341+ int main () {
342+ SplayTree bst;
343+ bst.insert (33 );
344+ bst.insert (44 );
345+ bst.insert (67 );
346+ bst.insert (5 );
347+ bst.insert (89 );
348+ bst.insert (41 );
349+ bst.insert (98 );
350+ bst.insert (1 );
351+ bst.prettyPrint ();
352+ bst.searchTree (33 );
353+ bst.searchTree (44 );
354+ bst.prettyPrint ();
355+ bst.deleteNode (89 );
356+ bst.deleteNode (67 );
357+ bst.deleteNode (41 );
358+ bst.deleteNode (5 );
359+ bst.prettyPrint ();
360+ bst.deleteNode (98 );
361+ bst.deleteNode (1 );
362+ bst.deleteNode (44 );
363+ bst.deleteNode (33 );
364+ bst.prettyPrint ();
365+ return 0 ;
366+ }
0 commit comments