What could I improve in this code? Any constructive criticism is highly appreciated, especially about the recursion and how I could make the code more legible/understandable - because even I'll have issues to understand what's what if I look at it in a few days (and I couldn't really find a way to explain in comments the recursive methods):
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
class Branch
{
friend class Tree;
private:
Branch* parent;
std::vector<Branch*> children;
int y;
int x;
private:
Branch()
:parent(0), x(0), y(0)
{
}
Branch(const Branch& another)
{
}
~Branch()
{
parent = 0;
children.clear();
x = 0;
y = 0;
}
private:
//find the index in the children
unsigned int findIndex()
{
//assume parent != 0
for (unsigned int k = 0; k < parent->children.size(); k++)
{
if (parent->children[k] == this)
return k;
}
//if it's not part of the children I messed somewhere else in the code
//so you'll get an out of bounds index
return parent->children.size();
}
void shiftChildren(int shift)
{
for (auto iter = children.begin(); iter != children.end(); iter++)
{
(*iter)->x += 2 * shift;
(*iter)->shiftChildren(shift);
}
return;
}
//shift the parents by shift
//and every other cell right of our cell by shift
void shiftRightSide( int shift )
{
if (parent == 0)
return;
parent->x += shift;
for (unsigned int k = findIndex()+1; k<parent->children.size(); k++)
{
parent->children[k]->x += 2 * shift;
parent->children[k]->shiftChildren(shift);
}
return parent->shiftRightSide( shift );
}
Branch* findRightmost()
{
if (children.empty())
return this;
children.back()->findRightmost();
}
//ignore this
int countSpaces(const std::string& str)
{
if (str == "")
return 0;
unsigned int counter = 0;
for (unsigned int k = 0; k < str.size(); k++)
{
if (str[k] == ' ')
counter++;
}
return counter+1;
}
void displayChildren(std::vector<std::string>& map, unsigned int level)
{
if (children.empty())
return;
level++;
if (map.size()-1 < level)
{
map.push_back("");
}
int prevX = map[level].size();
for (auto iter = children.begin(); iter != children.end(); iter++)
{
for (int k = 0; k < (*iter)->x - prevX; k++)
{
map[level] += " ";
}
map[level] += "*";
(*iter)->displayChildren(map, level);
prevX = (*iter)->x+1;
}
return;
}
};
class Tree
{
private:
std::vector<Branch*> branches;
public:
Branch root;
int dx;
int dy;
public:
Tree( int dx = 1, int dy = 1)
:dx(dx), dy(dy)
{
}
Branch* add(Branch& another)
{
Branch* temp = new Branch();
branches.push_back(temp);
temp->parent = &another;
temp->x = another.x;
temp->y = another.y + dy;
if (!another.children.empty())
{
//just for spacing - doesn't work
//if (another.children.back()->findRightmost() == another.children.back())
//{
temp->x = another.children.back()->findRightmost()->x + 2*dx;
temp->shiftRightSide(dx);
/*}
else
{
temp->x = another.children.back()->findRightmost()->x + 4 * dx;
temp->shiftRightSide(2*dx);
}*/
}
another.children.push_back(temp);
return temp;
}
void printStructure( std::ostream& os )
{
std::vector<std::string> map;
map.push_back("");
for (int k = 0; k < root.x; k++)
{
map[0] += " ";
}
map[0] += "*";
root.displayChildren(map, 0);
for (unsigned int k = 0; k < map.size(); k++)
{
/*map[k] += "\n";
os.write(map[k].c_str(), map[k].size());*/
os << map[k] << std::endl;
}
return;
}
void populate(Branch& another, int level)
{
level--;
if (level == 0)
return;
Branch* temp = 0;
for (int k = 0; k < std::rand() % 5; k++)
{
temp = add(another);
populate(*temp, level);
}
}
~Tree()
{
for (auto iter = branches.begin(); iter != branches.end(); iter++)
{
delete *iter;
}
branches.clear();
dx = 0;
dy = 0;
}
};
int main()
{
Tree myTree;
myTree.populate(myTree.root, 10);
std::ofstream file("tree.txt");
myTree.printStructure(file);
file.close();
//std::cin.sync();
//std::cin.ignore();
return 0;
}
It's supposed to create a structure of a tree and print it (use notepad to open it).