O
First, a subparagraph: A node is not a tree, just as a tooth is not an animal.In your program there is a class that manages the nodes. Nodes are an inner part of the tree structure and, as such, should not be happily exposed to the rest of the program.Consider implementing a class that manages the tree:class Arbol
{
public:
void Insertar(char valor);
void Eliminar(char valor);
// ...
private:
Nodo* root;
};
I mean, clearly doesn't order them well.He's ordering them right. What happens is that you are treating them as if they were character strings, that is,100 -> primer nodo
0 -> '0' < '1', nodo a la izquierda de 100
50 -> '5' > '1', nodo a la derecha de 100
35 -> '3' > '1' y '3' < '5', nodo a la izquierda de 50
But I would also like to accept Numbers and Names. Do you have any idea how I could accomplish this?You mean you can mix all that into a single tree? So the first thing you have to determine is a mechanism that allows you to compare all those elements to each other:How do you compare a character chain and a number?How do you compare a character and a number?How do you compare a character to a string?Since these mechanisms have not been determined in the question, this branch of development stands here.Yeah, instead, what you'd like is to use Nodo to create different trees (a tree of numbers, another string text, another of loose characters, ...), then you could choose to use templates.We can start by defining the comparisons:// Comparador por defecto
template<class T>
struct LessThanComparator
{
bool Compare(T const& a, T const& b) const
{ return a < b; }
};
Both native types, int, charLike class std::string have a proper overload of the operator <So the comparing job could end here. Only if we need a special comparison, for example if we need to compare strings without taking into account the use of capitals, then we could create a special comparator:struct CaseInsensitiveComparator
{
bool Compare(std::string const& a, std::string const& b)
{
size_t size = a.size() < b.size() ? a.size() : b.size();
for (size_t i = 0; i < size; ++i)
{
char charA = tolower(a[i]);
char charB = tolower(b[i]);
if (charA < charB)
return true;
else if( charA > charB )
return false;
}
return a.size() < b.size();
};
And with this we would already have all the necessary wits to create our class Nodo:template<class T, class Comparator = LessThanComparator<T>>
struct Nodo
{
T dato;
Nodo *padre;
Nodo *izq;
Nodo *der;
explicit Nodo(T const& value, Nodo* parent = nullptr)
: dato{value}
, padre{parent}
, izq{nullptr}
, der{nullptr}
{ }
bool operator<(Nodo const& other) const
{
Comparator c;
return c.Compare(dato, other.dato);
}
};
In this way, inserting a new node into the tree is now easier:template<class T>
void Insertar(T const& valor)
{
Nodo * nodo = /* raiz del arbol */;
Nodo * nuevo = new Nodo(valor);
while( true )
{
if( nodo->Compare(nuevo) )
{
if( nodo->der = nullptr )
{
nodo->der = nuevo;
nuevo->padre = nodo;
return;
}
else
{
nodo = nodo->der;
}
}
else if( nuevo->Compare(nodo) )
{
if( nodo->izq == nullptr )
{
nodo->izq = nuevo;
nuevo->padre = nodo;
return;
}
else
{
nodo = nodo->izq;
}
}
else // Ambos nodos tienen el mismo valor
{
delete nuevo;
return;
}
}
}