Added avl height benchmark

This commit is contained in:
2025-05-06 19:02:00 +02:00
parent e45091b066
commit 93311c4ad5
12 changed files with 328 additions and 94 deletions
+1 -2
View File
@@ -44,8 +44,7 @@ def plot(program_name, sequences, array_size):
plt.savefig(f"./benchmarks/{program_name}.png") plt.savefig(f"./benchmarks/{program_name}.png")
if __name__ == "__main__": if __name__ == "__main__":
# program_names = ["insertion", "selection", "heapsort", "mergesort"] program_names = ["insertion", "selection", "heapsort", "mergesort"]
program_names = ["heapsort"]
sequence_types = ["random", "sorted", "reversed", "constant", "v_shaped"] sequence_types = ["random", "sorted", "reversed", "constant", "v_shaped"]
array_sizes = [i for i in range(1000, 15001, 1000)] array_sizes = [i for i in range(1000, 15001, 1000)]
tests = 10 tests = 10
-6
View File
@@ -1,6 +0,0 @@
5
12
65
233
87
23
+1 -1
View File
@@ -1,3 +1,3 @@
benchmark benchmark
results.csv *.csv
charts/ charts/
+26
View File
@@ -0,0 +1,26 @@
Structure,Height
2000,10
4000,11
6000,12
8000,12
10000,13
12000,13
14000,13
16000,13
18000,14
20000,14
22000,14
24000,14
26000,14
28000,14
30000,14
32000,14
34000,15
36000,15
38000,15
40000,15
42000,15
44000,15
46000,15
48000,15
50000,15
1 Structure Height
2 2000 10
3 4000 11
4 6000 12
5 8000 12
6 10000 13
7 12000 13
8 14000 13
9 16000 13
10 18000 14
11 20000 14
12 22000 14
13 24000 14
14 26000 14
15 28000 14
16 30000 14
17 32000 14
18 34000 15
19 36000 15
20 38000 15
21 40000 15
22 42000 15
23 44000 15
24 46000 15
25 48000 15
26 50000 15
+86
View File
@@ -0,0 +1,86 @@
#include "avl.h"
#include "algorithm"
int getHeight(AVL_tree *root) {
if (!root)
return 0;
return root->height;
}
AVL_tree *rightRotate(AVL_tree *y) {
AVL_tree *x = y->left;
AVL_tree *T2 = x->right;
x->right = y;
y->left = T2;
y->height = 1 + std::max(getHeight(y->left), getHeight(y->right));
x->height = 1 + std::max(getHeight(x->left), getHeight(x->right));
return x;
}
AVL_tree *leftRotate(AVL_tree *x) {
AVL_tree *y = x->right;
AVL_tree *T2 = y->left;
y->left = x;
x->right = T2;
x->height = 1 + std::max(getHeight(x->left), getHeight(x->right));
y->height = 1 + std::max(getHeight(y->left), getHeight(y->right));
return y;
}
int getBalance(AVL_tree *root) {
if (!root)
return 0;
return getHeight(root->left) - getHeight(root->right);
}
AVL_tree *insertAVL(AVL_tree *root, int value) {
if (root == nullptr) {
return new AVL_tree{value, nullptr, nullptr, 1};
}
if (value < root->info) {
root->left = insertAVL(root->left, value);
} else if (value > root->info) {
root->right = insertAVL(root->right, value);
} else {
return root;
}
root->height = 1 + std::max(getHeight(root->left), getHeight(root->right));
int balance = getBalance(root);
if (balance > 1 && value < root->left->info) {
return rightRotate(root);
}
if (balance < -1 && value > root->right->info) {
return leftRotate(root);
}
if (balance > 1 && value > root->left->info) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
if (balance < -1 && value < root->right->info) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
void deleteAVL(AVL_tree *root){
if (root != nullptr) {
deleteAVL(root->left);
deleteAVL(root->right);
delete root;
}
}
+13
View File
@@ -0,0 +1,13 @@
struct AVL_tree {
int info;
AVL_tree *left;
AVL_tree *right;
int height;
};
int getHeight(AVL_tree *root);
AVL_tree *insertAVL(AVL_tree *root, int value);
AVL_tree *rotateLeft(AVL_tree *root);
AVL_tree *rotateRight(AVL_tree *root);
AVL_tree *searchAVL(AVL_tree *root, int value);
void deleteAVL(AVL_tree *root);
+126 -82
View File
@@ -1,97 +1,123 @@
#include "avl/avl.h"
#include "bst/bst.h" #include "bst/bst.h"
#include "list/list.h" #include "list/list.h"
#include <chrono>
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#include <set> #include <ostream>
#include <random> #include <random>
#include <chrono> #include <set>
void measureList(std::set<int> *sequence, FILE *file){ void measureList(std::set<int> *sequence, FILE *file) {
float buildTime = 0, searchTime = 0, deleteTime = 0; float buildTime = 0, searchTime = 0, deleteTime = 0;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
std::cout << "- Running list " << i + 1 << "/10\r"; std::cout << "- Running list " << i + 1 << "/10\r";
fflush(stdout); fflush(stdout);
// Measure build time // Measure build time
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
List *head = nullptr; List *head = nullptr;
for (int value : *sequence) { for (int value : *sequence) {
head = insert(head, value); head = insert(head, value);
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Now we run the search
start = std::chrono::high_resolution_clock::now();
for (int value : *sequence) {
search(head, value);
}
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Measure deletion time for list
start = std::chrono::high_resolution_clock::now();
while(head != nullptr){
head = remove(head);
}
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
} }
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
buildTime /= 10; // Now we run the search
searchTime /= 10; start = std::chrono::high_resolution_clock::now();
deleteTime /= 10; for (int value : *sequence) {
search(head, value);
}
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
std::cout << "- List built in " << buildTime << "ms | searched in " << searchTime << "ms | deleted in " << deleteTime << "ms" << std::endl; // Measure deletion time for list
fprintf(file, "List,%f,%f,%f\n", buildTime, searchTime, deleteTime); start = std::chrono::high_resolution_clock::now();
while (head != nullptr) {
head = remove(head);
}
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
}
buildTime /= 10;
searchTime /= 10;
deleteTime /= 10;
std::cout << "- List built in " << buildTime << "ms | searched in "
<< searchTime << "ms | deleted in " << deleteTime << "ms"
<< std::endl;
fprintf(file, "List,%f,%f,%f\n", buildTime, searchTime, deleteTime);
} }
void measureBST(std::set<int> *sequence, FILE *file){ void measureBST(std::set<int> *sequence, FILE *file) {
float buildTime = 0, searchTime = 0, deleteTime = 0; float buildTime = 0, searchTime = 0, deleteTime = 0;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
std::cout << "- Running bst " << i + 1 << "/10\r"; std::cout << "- Running bst " << i + 1 << "/10\r";
fflush(stdout); fflush(stdout);
// Measure build time // Measure build time
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
Tree *root = nullptr; Tree *root = nullptr;
for (int value : *sequence) { for (int value : *sequence) {
root = insert(root, value); root = insert(root, value);
}
root = balance(root);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Now we run the search
start = std::chrono::high_resolution_clock::now();
for (int value : *sequence) {
search(root, value);
}
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Measure deletion time for tree
start = std::chrono::high_resolution_clock::now();
deleteTree(root);
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
} }
root = balance(root);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
buildTime /= 10; // Now we run the search
searchTime /= 10; start = std::chrono::high_resolution_clock::now();
deleteTime /= 10; for (int value : *sequence) {
search(root, value);
}
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
std::cout << "- Tree built in " << buildTime << "ms | searched in " << searchTime << "ms | deleted in " << deleteTime << "ms" << std::endl; // Measure deletion time for tree
fprintf(file, "BST,%f,%f,%f\n", buildTime, searchTime, deleteTime); start = std::chrono::high_resolution_clock::now();
deleteTree(root);
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
}
buildTime /= 10;
searchTime /= 10;
deleteTime /= 10;
std::cout << "- Tree built in " << buildTime << "ms | searched in "
<< searchTime << "ms | deleted in " << deleteTime << "ms"
<< std::endl;
fprintf(file, "BST,%f,%f,%f\n", buildTime, searchTime, deleteTime);
}
void benchmarkAVL(std::set<int> *sequence, FILE *file) {
Tree *bst = nullptr;
for (int value : *sequence) {
bst = insert(bst, value);
}
int heightBST = getHeight(bst, 0);
deleteTree(bst);
AVL_tree *avl = nullptr;
for (int value : *sequence) {
avl = insertAVL(avl, value);
}
int heightAVL = getHeight(avl);
deleteAVL(avl);
fprintf(file, "%d,%d\n", heightBST, heightAVL);
} }
int main() { int main() {
@@ -100,9 +126,25 @@ int main() {
std::mt19937 gen(rd()); std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 1000000); std::uniform_int_distribution<> dis(1, 1000000);
// Open a file for writing results int mode = 1;
FILE *file = fopen("results.csv", "w"); std::cout << "Select benchmark to run:\n 1 - Benchmark List vs BST\n 2 - "
fprintf(file, "Elements,Structure,BuildTime,SearchTime,DeleteTime\n"); "Benchmark BST vs AVL"
<< std::endl;
std::cin >> mode;
if (mode < 1 && mode > 2) {
mode = 1;
}
FILE *file;
if (mode == 1) {
// Open a file for writing results
file = fopen("results.csv", "w");
fprintf(file, "Structure,BuildTime,SearchTime,DeleteTime\n");
} else {
file = fopen("avl.csv", "w");
std::fprintf(file, "Structure,Height\n");
}
for (int n = 1; n < 26; n++) { for (int n = 1; n < 26; n++) {
std::set<int> sequence; std::set<int> sequence;
@@ -113,12 +155,14 @@ int main() {
// Display this like a cascade // Display this like a cascade
std::cout << "Running tests for " << n * 1000 << " elements..." std::cout << "Running tests for " << n * 1000 << " elements..."
<< std::endl; << std::endl;
if (mode == 1) {
measureList(&sequence, file); measureList(&sequence, file);
measureBST(&sequence, file); measureBST(&sequence, file);
} else {
benchmarkAVL(&sequence, file);
}
} }
fclose(file); fclose(file);
return 0; return 0;
} }
+8
View File
@@ -58,3 +58,11 @@ void deleteTree(Tree *root) {
delete root; delete root;
} }
} }
int getHeight(Tree *root, int height) {
if (root == nullptr) return height;
height += 1;
int leftHeight = getHeight(root->left, height);
int rightHeight = getHeight(root->right, height);
return std::max(leftHeight, rightHeight) + 1;
}
+1
View File
@@ -12,3 +12,4 @@ void traverseInOrder(Tree *root,std::vector<int> &vec);
Tree *rebuild(std::vector<int> *vec, int start, int end); Tree *rebuild(std::vector<int> *vec, int start, int end);
Tree *balance(Tree *root); Tree *balance(Tree *root);
void deleteTree(Tree *root); void deleteTree(Tree *root);
int getHeight(Tree *root, int height);
+14 -3
View File
@@ -1,9 +1,9 @@
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
def plot(header:str, first:list[int], second:list[int], log=False): def plot(header:str, first:list[int], second:list[int], log=False, labels=("Lista", "Drzewo BST")):
plt.figure(figsize=(10, 6)) plt.figure(figsize=(10, 6))
plt.plot(range(1000,25001,1000), first, label="Lista") plt.plot(range(1000,25001,1000), first, label=labels[0])
plt.plot(range(1000,25001,1000), second, label="Drzewo BST") plt.plot(range(1000,25001,1000), second, label=labels[1])
plt.xlabel("Rozmiar tablicy") plt.xlabel("Rozmiar tablicy")
plt.ylabel("Czas (ms)") plt.ylabel("Czas (ms)")
if log: if log:
@@ -45,3 +45,14 @@ if __name__ == "__main__":
plot("Tworzenie", listTimes['build'], bstTimes['build']) plot("Tworzenie", listTimes['build'], bstTimes['build'])
plot("Wyszukiwanie", listTimes['search'], bstTimes['search'], log=True) plot("Wyszukiwanie", listTimes['search'], bstTimes['search'], log=True)
plot("Usuwanie", listTimes['delete'], bstTimes['delete']) plot("Usuwanie", listTimes['delete'], bstTimes['delete'])
with open("avl.csv", "r") as file:
data = file.read()
lines = data.split('\n')
headers = lines[0].split(',')
values = [line.split(',') for line in lines[1:-1]]
bstHeights = [int(x[0]) for x in values]
avlHeights = [int(x[1]) for x in values]
plot("AVl", bstHeights, avlHeights, log=True, labels=("Drzewo BST", "Drzewo AVL"))
+51
View File
@@ -0,0 +1,51 @@
Elements,Structure,BuildTime,SearchTime,DeleteTime
List,0.543320,0.520767,0.010243
BST,1.544223,0.025997,0.008951
List,3.479965,3.461854,0.022565
BST,9.890946,0.142389,0.026754
List,7.862325,7.733483,0.037077
BST,20.342850,0.257188,0.048077
List,14.756193,14.451564,0.044844
BST,37.088211,0.312305,0.054895
List,22.063259,21.787954,0.056064
BST,51.029690,0.396568,0.065577
List,26.197474,26.072092,0.062295
BST,73.239220,0.458283,0.074890
List,39.307865,38.355278,0.069399
BST,107.733963,0.671136,0.093605
List,59.704353,59.331749,0.093153
BST,164.595337,1.058345,0.120158
List,75.755898,74.383286,0.101044
BST,209.177338,1.228530,0.138253
List,94.265694,93.193260,0.122636
BST,270.258728,1.591327,0.164845
List,104.814880,101.211784,0.116452
BST,246.079788,0.931309,0.133289
List,112.470276,110.182449,0.117044
BST,276.451080,0.975446,0.137597
List,126.718018,124.866295,0.121890
BST,315.444519,1.054176,0.142032
List,145.154541,141.603271,0.127330
BST,362.195190,1.103273,0.145592
List,168.838623,166.042252,0.132073
BST,402.726440,1.198986,0.153952
List,193.290436,189.238907,0.140827
BST,487.910156,1.276635,0.158837
List,220.266205,214.658295,0.146799
BST,504.256195,1.505627,0.168319
List,241.377975,235.950562,0.152117
BST,580.977173,1.557522,0.173307
List,266.187561,264.576538,0.177301
BST,724.846436,2.546352,0.223694
List,306.509338,306.340973,0.191684
BST,785.615173,2.440228,0.220973
List,326.952972,319.279846,0.188148
BST,793.774536,1.972353,0.209726
List,347.416840,340.725769,0.190998
BST,952.154907,2.114705,0.209531
List,374.497253,370.216095,0.194421
BST,887.039246,2.150400,0.221431
List,405.752655,403.273956,0.201055
BST,1040.535645,2.334295,0.223531
List,449.462952,439.051361,0.209022
BST,1124.903564,2.481752,0.235188
1 Elements,Structure,BuildTime,SearchTime,DeleteTime
2 List,0.543320,0.520767,0.010243
3 BST,1.544223,0.025997,0.008951
4 List,3.479965,3.461854,0.022565
5 BST,9.890946,0.142389,0.026754
6 List,7.862325,7.733483,0.037077
7 BST,20.342850,0.257188,0.048077
8 List,14.756193,14.451564,0.044844
9 BST,37.088211,0.312305,0.054895
10 List,22.063259,21.787954,0.056064
11 BST,51.029690,0.396568,0.065577
12 List,26.197474,26.072092,0.062295
13 BST,73.239220,0.458283,0.074890
14 List,39.307865,38.355278,0.069399
15 BST,107.733963,0.671136,0.093605
16 List,59.704353,59.331749,0.093153
17 BST,164.595337,1.058345,0.120158
18 List,75.755898,74.383286,0.101044
19 BST,209.177338,1.228530,0.138253
20 List,94.265694,93.193260,0.122636
21 BST,270.258728,1.591327,0.164845
22 List,104.814880,101.211784,0.116452
23 BST,246.079788,0.931309,0.133289
24 List,112.470276,110.182449,0.117044
25 BST,276.451080,0.975446,0.137597
26 List,126.718018,124.866295,0.121890
27 BST,315.444519,1.054176,0.142032
28 List,145.154541,141.603271,0.127330
29 BST,362.195190,1.103273,0.145592
30 List,168.838623,166.042252,0.132073
31 BST,402.726440,1.198986,0.153952
32 List,193.290436,189.238907,0.140827
33 BST,487.910156,1.276635,0.158837
34 List,220.266205,214.658295,0.146799
35 BST,504.256195,1.505627,0.168319
36 List,241.377975,235.950562,0.152117
37 BST,580.977173,1.557522,0.173307
38 List,266.187561,264.576538,0.177301
39 BST,724.846436,2.546352,0.223694
40 List,306.509338,306.340973,0.191684
41 BST,785.615173,2.440228,0.220973
42 List,326.952972,319.279846,0.188148
43 BST,793.774536,1.972353,0.209726
44 List,347.416840,340.725769,0.190998
45 BST,952.154907,2.114705,0.209531
46 List,374.497253,370.216095,0.194421
47 BST,887.039246,2.150400,0.221431
48 List,405.752655,403.273956,0.201055
49 BST,1040.535645,2.334295,0.223531
50 List,449.462952,439.051361,0.209022
51 BST,1124.903564,2.481752,0.235188
+1
View File
@@ -19,6 +19,7 @@
[ [
clang-tools clang-tools
cmake cmake
libgcc
codespell codespell
conan conan
cppcheck cppcheck