I lost the thread where we were talking about this, but decided to make a crude and rough hack at expressing what I was trying to say. I did not finish the used/unused ideas, but put enough in to see where it was going. It may have bugs etc, I cranked it out pretty fast.
*Its going to need some TLC if you delete the root node and then put it back in.
*The only interesting part is insert. the rest is just filler really.
advantages over pure tree:
- can load and store tree to file directly without a rebuild though a more complex node type would have serialize needs.
- can iterate as a vector to touch all nodes, etc
- less page faults/ solid block of memory used
- fairly compact, vs the classic computed index tree to array approach
disadvantages: its a convoluted oddity just to get tree traversals and BST like behavior, eg sorted inserts? Im not a big tree guy, so I dunno what other practical use such a thing might have?
/shrug anyway, it was interesting to poke at, but I probably won't clean it up and finish it given I don't have much use for it.
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 143 144 145 146 147
|
#include <cstdio> //a pile of common includes. not all needed here.
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <ctype.h>
#include <stdint.h>
#include <cmath>
#include <vector>
#include <numeric>
#include <random>
#include <iomanip>
#include <fstream>
#include <bits/stdc++.h>
#include <set>
#include <ctime>
#include <numeric>
//#include <pthread.h>
//#include <unistd.h>
using namespace std;
struct vtnode
{
int data;
int left;
int right;
bool used;
vtnode(){left = right = 0; used = false;}
vtnode(int d){data = d; used = true; left = right = 0;}
};
class vectree
{
vector<vtnode> vn;
vector<int> unused;
int count;
public:
vectree(){count = 0; vtnode x; vn.push_back(x);}
void ins(int in)
{
static vtnode tmp(0);
static int dest = 0;
if(count == 0) //special case empty tree
{
count++;
vn[0].data = in;
vn[0].left = vn[0].right= 0;
vn[0].used = true;
return;
}
if(unused.size())
{
dest = unused[unused.size()-1];
unused.pop_back();
}
else
{
dest = vn.size();
tmp.data = in;
vn.push_back(tmp);
}
for(int i = 0; i < count;)
{
if(in < vn[i].data && vn[i].left)
{
i = vn[i].left;
}
else if(in < vn[i].data && vn[i].left == 0)
{
vn[i].left = dest;
count++;
return;
}
if(in >= vn[i].data && vn[i].right)
{
i = vn[i].right;
}
else if(in >= vn[i].data && vn[i].right == 0)
{
vn[i].right = dest;
count++;
return;
}
}
}
void save()
{
ofstream ofs("tr.bin",ios::binary);
unsigned int s = vn.size();
ofs.write((char*)&s, sizeof(unsigned int));
ofs.write((char*)&vn[0], vn.size()*sizeof(vtnode));
ofs.close();
}
void load()
{
ifstream ifs("tr.bin",ios::binary);
unsigned int s;
ifs.read((char*)&s, sizeof(unsigned int));
vn.resize(s);
ifs.read((char*)&vn[0], s*sizeof(vtnode));
ifs.close();
unused.clear(); //or we could save unused and load that too.
for(int x = 0; x < vn.size(); x++)
if(vn[x].used == false)
unused.push_back(x);
}
void del (int in)
{
//mark unused, add index to unused vector etc
}
void prn(int pos = 0)
{
if(vn[pos].left) prn(vn[pos].left);
cout << vn[pos].data << endl;
if(vn[pos].right) prn(vn[pos].right);
}
void vecprn()
{
for(auto x : vn)
cout << x.data << endl;
}
};
int main()
{
vectree v;
v.ins(10);
v.ins(5);
v.ins(7);
v.ins(15);
//v.prn();
vectree v2;
v.save();
v2.load();
v2.prn();
v2.vecprn();
return 0;
}
| |
outputs as tree and then as vector
5
7
10
15
10
5
7
15