Во-первых, приведенный код на самом деле не описывает три. Скорее, это дерево, содержащее пару элементов в каждом узле (T*
и unsigned
). Вы можете по дисциплине использовать дерево кортежей в качестве дерева, но это только по соглашению, а не по принуждению. Это одна из причин того, почему вам так трудно реализовать operator++
.
Вам нужно, чтобы каждый Trie
содержал разделенную слева направо ADT, а не только необработанные элементы. Это слой абстракции, который чаще встречается в функциональных языках (например, Scala's Either ). К сожалению, система типов C ++ не достаточно мощна, чтобы делать что-то такое элегантное. Однако ничто не мешает вам сделать это:
template <class L, class R>
class Either
{
public:
Either(L *l) : left(l), right(0)
{}
Either(R *r) : left(0), right(r)
{}
L *get_left() const
{
return left;
}
R *get_right() const
{
return right;
}
bool is_left() const
{
return left != 0;
}
bool is_right() const
{
return right != 0;
}
private:
L *left;
R *right;
};
Тогда члены вашего Trie
будут определены следующим образом:
private:
Either<unsigned, T*> disjoint;
vector<Trie<T> *> children; // english pluralization
Trie<T> * parent;
Я играю быстро и свободно с вашими указателями, но вы понимаете суть того, что я говорю. Важным битом является то, что ни один данный узел не может содержать и , unsigned
и T*
.
.
Попробуйте и посмотрите, поможет ли это. Я думаю, вы обнаружите, что возможность легко определить, находитесь ли вы на листе или на ветке, чрезвычайно поможет вам в вашей попытке выполнить итерацию.