-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAVLTree.hpp
More file actions
142 lines (124 loc) · 4.18 KB
/
AVLTree.hpp
File metadata and controls
142 lines (124 loc) · 4.18 KB
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
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // For std::max
#include <memory> // For std::unique_ptr
/*
A node in AVL Tree
K Key type (e.g., post timestamp)
V Value type (e.g., post content string)
*/
template <typename K, typename V>
struct AVLNode {
K key;
V value;
std::unique_ptr<AVLNode<K, V>> left;
std::unique_ptr<AVLNode<K, V>> right;
int height;
AVLNode(K k, V v) : key(k), value(v), left(nullptr), right(nullptr), height(1) {}
};
/*
AVL Tree Implementation,, Stores posts sorted by creation time.
K Key type (timestamp)
V Value type (post content)
*/
template <typename K, typename V>
class AVLTree {
private:
std::unique_ptr<AVLNode<K, V>> root;
int getHeight(const std::unique_ptr<AVLNode<K, V>>& node) {
return node ? node->height : 0;
}
int getBalance(const std::unique_ptr<AVLNode<K, V>>& node) {
return node ? (getHeight(node->left) - getHeight(node->right)) : 0;
}
void updateHeight(std::unique_ptr<AVLNode<K, V>>& node) {
if (node) {
node->height = 1 + std::max(getHeight(node->left), getHeight(node->right));
}
}
//Right Rotation
std::unique_ptr<AVLNode<K, V>> rightRotate(std::unique_ptr<AVLNode<K, V>> y) {
std::unique_ptr<AVLNode<K, V>> x = std::move(y->left);
std::unique_ptr<AVLNode<K, V>> T2 = std::move(x->right);
x->right = std::move(y);
x->right->left = std::move(T2); // y->left = T2
updateHeight(x->right);
updateHeight(x);
return x;
}
//Left Rotation
std::unique_ptr<AVLNode<K, V>> leftRotate(std::unique_ptr<AVLNode<K, V>> x) {
std::unique_ptr<AVLNode<K, V>> y = std::move(x->right);
std::unique_ptr<AVLNode<K, V>> T2 = std::move(y->left);
y->left = std::move(x);
y->left->right = std::move(T2); // x->right = T2
updateHeight(y->left);
updateHeight(y);
return y;
}
//Inserting Key,Value pair using Recursion
std::unique_ptr<AVLNode<K, V>> insert(std::unique_ptr<AVLNode<K, V>> node, K key, V value) {
if (!node) {
return std::make_unique<AVLNode<K, V>>(key, value);
}
if (key < node->key) {
node->left = insert(std::move(node->left), key, value);
} else if (key > node->key) {
node->right = insert(std::move(node->right), key, value);
} else {
// No duplication of keys for timestamps
return node;
}
updateHeight(node);
int balance = getBalance(node);
//Rebalancing (if needed)
// Left Left Case
if (balance > 1 && key < node->left->key) {
return rightRotate(std::move(node));
}
// Right Right Case
if (balance < -1 && key > node->right->key) {
return leftRotate(std::move(node));
}
// Left Right Case
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(std::move(node->left));
return rightRotate(std::move(node));
}
// Right Left Case
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(std::move(node->right));
return leftRotate(std::move(node));
}
return node;
}
/*
Recursive helper for reverse in-order traversal (gets most recent first).
posts->Vector to store results
count->Current number of posts found
*/
void getReverseInOrder(const std::unique_ptr<AVLNode<K, V>>& node, std::vector<V>& posts, int& count, int N) {
if (!node || (N != -1 && count >= N)) {
return;
}
getReverseInOrder(node->right, posts, count, N);
if (N == -1 || count < N) {
posts.push_back(node->value);
count++;
}
getReverseInOrder(node->left, posts, count, N);
} //Right -> Current -> Left
public:
AVLTree() : root(nullptr) {}
void insert(K key, V value) {
root = insert(std::move(root), key, value);
}
std::vector<V> getRecentPosts(int N) {
std::vector<V> posts;
int count = 0;
getReverseInOrder(root, posts, count, N);
return posts;
}
};