This repository was archived by the owner on Feb 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScapegoat_Tree.cpp
More file actions
129 lines (129 loc) · 4.01 KB
/
Scapegoat_Tree.cpp
File metadata and controls
129 lines (129 loc) · 4.01 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
#include <iostream>
#include <cmath>
template <typename T>
class ScapegoatTree {
private:
struct Node {
T key;
Node* left;
Node* right;
Node* parent;
Node(const T& k, Node* l = nullptr, Node* r = nullptr, Node* p = nullptr)
: key(k), left(l), right(r), parent(p) {}
};
Node* root;
int size;
int maxSize;
public:
ScapegoatTree(double alpha = 0.75) : root(nullptr), size(0) {
maxSize = alpha * pow(2, log2(1.0 * size + 1));
}
void insert(const T& key) {
insert(key, root);
}
void remove(const T& key) {
remove(key, root);
}
bool search(const T& key) const {
return search(key, root);
}
private:
void insert(const T& key, Node*& currentNode) {
if (currentNode == nullptr) {
currentNode = new Node(key);
++size;
if (size > maxSize) {
rebuild(currentNode);
}
} else if (key < currentNode->key) {
insert(key, currentNode->left);
} else if (key > currentNode->key) {
insert(key, currentNode->right);
}
}
void remove(const T& key, Node*& currentNode) {
if (currentNode == nullptr) {
return;
}
if (key < currentNode->key) {
remove(key, currentNode->left);
} else if (key > currentNode->key) {
remove(key, currentNode->right);
} else {
if (currentNode->left == nullptr) {
Node* temp = currentNode;
currentNode = currentNode->right;
delete temp;
} else if (currentNode->right == nullptr) {
Node* temp = currentNode;
currentNode = currentNode->left;
delete temp;
} else {
Node* successor = findMin(currentNode->right);
currentNode->key = successor->key;
remove(successor->key, currentNode->right);
}
--size;
}
if (size > maxSize * 2) {
rebuild(currentNode);
}
}
bool search(const T& key, const Node* currentNode) const {
if (currentNode == nullptr) {
return false;
}
if (key == currentNode->key) {
return true;
} else if (key < currentNode->key) {
return search(key, currentNode->left);
} else {
return search(key, currentNode->right);
}
}
Node* findMin(Node* currentNode) const {
while (currentNode->left != nullptr) {
currentNode = currentNode->left;
}
return currentNode;
}
void rebuild(Node*& currentNode) {
T* keys = new T[size];
int index = 0;
traverseInOrder(currentNode, keys, index);
currentNode = buildBalancedTree(keys, 0, size - 1, nullptr);
maxSize = 2 * size;
delete[] keys;
}
void traverseInOrder(const Node* currentNode, T* keys, int& index) const {
if (currentNode == nullptr) {
return;
}
traverseInOrder(currentNode->left, keys, index);
keys[index++] = currentNode->key;
traverseInOrder(currentNode->right, keys, index);
}
Node* buildBalancedTree(const T* keys, int start, int end, Node* parent) {
if (start > end) {
return nullptr;
}
int mid = (start + end) / 2;
Node* newNode = new Node(keys[mid]);
newNode->parent = parent;
newNode->left = buildBalancedTree(keys, start, mid - 1, newNode);
newNode->right = buildBalancedTree(keys, mid + 1, end, newNode);
return newNode;
}
};
int main() {
ScapegoatTree<int> stree;
stree.insert(3);
stree.insert(1);
stree.insert(4);
stree.insert(2);
stree.insert(5);
std::cout << "Search for key 2: " << (stree.search(2) ? "Found" : "Not Found") << std::endl;
stree.remove(2);
std::cout << "Search for key 2: " << (stree.search(2) ? "Found" : "Not Found") << std::endl;
return 0;
}