Added avl height benchmark
This commit is contained in:
+1
-1
@@ -1,3 +1,3 @@
|
||||
benchmark
|
||||
results.csv
|
||||
*.csv
|
||||
charts/
|
||||
|
||||
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -1,97 +1,123 @@
|
||||
#include "avl/avl.h"
|
||||
#include "bst/bst.h"
|
||||
#include "list/list.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <ostream>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
#include <set>
|
||||
|
||||
void measureList(std::set<int> *sequence, FILE *file){
|
||||
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
||||
void measureList(std::set<int> *sequence, FILE *file) {
|
||||
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
std::cout << "- Running list " << i + 1 << "/10\r";
|
||||
fflush(stdout);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
std::cout << "- Running list " << i + 1 << "/10\r";
|
||||
fflush(stdout);
|
||||
|
||||
// Measure build time
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
List *head = nullptr;
|
||||
for (int value : *sequence) {
|
||||
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
|
||||
// Measure build time
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
List *head = nullptr;
|
||||
for (int value : *sequence) {
|
||||
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
|
||||
|
||||
buildTime /= 10;
|
||||
searchTime /= 10;
|
||||
deleteTime /= 10;
|
||||
// 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
|
||||
|
||||
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);
|
||||
// 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
|
||||
}
|
||||
|
||||
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){
|
||||
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
||||
void measureBST(std::set<int> *sequence, FILE *file) {
|
||||
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
std::cout << "- Running bst " << i + 1 << "/10\r";
|
||||
fflush(stdout);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
std::cout << "- Running bst " << i + 1 << "/10\r";
|
||||
fflush(stdout);
|
||||
|
||||
// Measure build time
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
Tree *root = nullptr;
|
||||
for (int value : *sequence) {
|
||||
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
|
||||
// Measure build time
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
Tree *root = nullptr;
|
||||
for (int value : *sequence) {
|
||||
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
|
||||
|
||||
buildTime /= 10;
|
||||
searchTime /= 10;
|
||||
deleteTime /= 10;
|
||||
// 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
|
||||
|
||||
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);
|
||||
// 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
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -100,9 +126,25 @@ int main() {
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> dis(1, 1000000);
|
||||
|
||||
// Open a file for writing results
|
||||
FILE *file = fopen("results.csv", "w");
|
||||
fprintf(file, "Elements,Structure,BuildTime,SearchTime,DeleteTime\n");
|
||||
int mode = 1;
|
||||
std::cout << "Select benchmark to run:\n 1 - Benchmark List vs BST\n 2 - "
|
||||
"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++) {
|
||||
std::set<int> sequence;
|
||||
@@ -113,12 +155,14 @@ int main() {
|
||||
// Display this like a cascade
|
||||
std::cout << "Running tests for " << n * 1000 << " elements..."
|
||||
<< std::endl;
|
||||
|
||||
measureList(&sequence, file);
|
||||
measureBST(&sequence, file);
|
||||
if (mode == 1) {
|
||||
measureList(&sequence, file);
|
||||
measureBST(&sequence, file);
|
||||
} else {
|
||||
benchmarkAVL(&sequence, file);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -58,3 +58,11 @@ void deleteTree(Tree *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;
|
||||
}
|
||||
|
||||
@@ -12,3 +12,4 @@ void traverseInOrder(Tree *root,std::vector<int> &vec);
|
||||
Tree *rebuild(std::vector<int> *vec, int start, int end);
|
||||
Tree *balance(Tree *root);
|
||||
void deleteTree(Tree *root);
|
||||
int getHeight(Tree *root, int height);
|
||||
|
||||
+14
-3
@@ -1,9 +1,9 @@
|
||||
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.plot(range(1000,25001,1000), first, label="Lista")
|
||||
plt.plot(range(1000,25001,1000), second, label="Drzewo BST")
|
||||
plt.plot(range(1000,25001,1000), first, label=labels[0])
|
||||
plt.plot(range(1000,25001,1000), second, label=labels[1])
|
||||
plt.xlabel("Rozmiar tablicy")
|
||||
plt.ylabel("Czas (ms)")
|
||||
if log:
|
||||
@@ -45,3 +45,14 @@ if __name__ == "__main__":
|
||||
plot("Tworzenie", listTimes['build'], bstTimes['build'])
|
||||
plot("Wyszukiwanie", listTimes['search'], bstTimes['search'], log=True)
|
||||
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"))
|
||||
|
||||
@@ -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
|
||||
|
Reference in New Issue
Block a user