I made an AVL tree in C++, and the tree is kept balanced successfully according to all of my tests.
The function addNode
should work in O(log(n)) (when n is the number of nodes in the tree), and it seems like my implementation satisfies it.
To verify, I wrote the following test:
#include "AVLTree.h"
#include "iostream"
#include <chrono>
#include <vector>
#include <random>
#include <algorithm>
#include <memory>
using namespace std;
using namespace std::chrono;
typedef high_resolution_clock Clock;
typedef Clock::time_point ClockTime;
auto ExecutionTime(ClockTime start_time, ClockTime end_time)
{
return duration_cast<nanoseconds>(end_time - start_time).count();
}
#define N 10000000
#define M 100000
int main(){
AVLTree<unsigned long long, unsigned long long> tree; // AVLTree<key type, value type>
ClockTime start_time;
ClockTime end_time;
std::vector<unsigned long long> vector;
for (unsigned long long i=0; i<N; i++) vector.push_back(i);
auto max_time = ExecutionTime(start_time, start_time); // currently zero, will get bigger.
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
shuffle (vector.begin(), vector.end(), std::default_random_engine(seed));
unsigned long long counter = 0;
for (auto i : vector){
start_time = Clock::now();
tree.addNode(i, i);
end_time = Clock::now();
max_time = max(max_time, ExecutionTime(start_time, end_time));
counter++;
if (counter == M){
cout << "Small add: " << max_time << endl;
}
}
cout << "Add: " << max_time << end;
}
Because the function works in θ(log(n)), for sufficiently large n, T(addNode)<clog(n) (T is the time function) for some constant c, and if we take a really tight one, we may assume T(addNode)=clog(n) for large enough n. That means that the above test should output:
Small add: x
Add: (<2x)
For some x, and most time it does, but I also got
Small add: 280100
Add: 14432000
Which is almost 100 times bigger. Assuming the implementation is correct, why did it happen (it happens pretty rarely)?