Хорошо, учитывая класс по линии
class quadTree {
short level;
Vec2f midpoint;
quadTree * nodes[4] = { NULL, NULL, NULL, NULL};
public:
void newPartition() {
float j = fWIDTH / 2 ^ level;
float k = fHEIGHT / 2 ^ level;
nodes[0] = new quadTree(level+1, midpoint[0] - j, midpoint[0] + k);
nodes[1] = new quadTree(level+1, midpoint[0] + j, midpoint[0] + k);
nodes[2] = new quadTree(level+1, midpoint[0] - j, midpoint[0] - k);
nodes[3] = new qaudTree(level+1, midpoint[0] + j, midpoint[0] - k);
}
}
Как я могу реализовать функцию, которая удаляет все узлы под текущим узлом дерева квадрантов без рекурсии, возможно, используя очередь? Как и в функции Clear ().
Прошу прощения за вопрос, я чувствую, что должен знать это и просто не могу понять это. Я посмотрел онлайн, но ничего не смог найти. Есть идеи?
Для любого примера кода, использующего очередь, просто используйте std :: queue.
РЕДАКТИРОВАТЬ ::
Хорошо, я думаю, что это то, что я собираюсь использовать для справки. Я думаю, что это должно работать, поправьте меня, если я ошибаюсь.
#include <queue>
void helpClear( bool notPassing, queue<quadTree> &q ) {
int count;
for ( int i; i < 4; i++ ) {
if ( node[i] != NULL){
q.push ( node[i] );
count++;
}
}
quadTree * Point;
if ( notPassing ){
for ( int i; i < count; i++ ){
Point = q.front();
q.pop();
Point -> helpClear(0, q);
}
for ( int i; i < 4; i ++ )
delete nodes[i];
}
}
void clear () {
queue <quadTree> q;
quadTree * Point;
helpClear(1,q);
while (!queue.empty() ) {
quadTree * Point;
Point = q.front();
q.pop();
Point -> helpClear(1,q);
delete Point;
}
for ( int i; i < 4; i++ )
nodes[i] = NULL;
}
helpClear () является частной функцией quadTree, а clear () является публичной функцией, которую вы вызываете для удаления всех узлов ниже текущего узла.
Есть две идеи (подходы):
1) Если вы можете контролировать все newPartition()
-действий в одной точке (например, на верхнем уровне), вы можете реализовать специальный буфер quadTree
указатели и собери в нем все узлы (любой из std
list
, vector
, queue
…)
В этом случае, когда вам нужно очистить все узлы, вы можете просто очистить все дочерние узлы с помощью указателей в этом буфере без использования стека.
2) Если ваше QuadTree использует строгий порядок узлов (в пространственном смысле), вы можете организовать все ваши указатели в одном контейнере. Например:
Уровень 0 (1 указатель):
1111
1111
1111
1111
Уровень 1 (4 указателя)
2233
2233
4455
4455
Уровень 2 (16 указателей)
ABEF
CDGH
IJMN
KLOP
В контейнере порядок будет таким:
12345ABCDEFGHIJKLOP
Отношения между уровнями могут быть решены с помощью математических вычислений, поскольку для каждого уровня требуется ровно 2 ^ N элементов.
Это решение не требует дополнительных указателей (и вообще 0 указателей) и решает проблему стека. Однако ему требуется больше времени для перехода от родителя к потомку и от потомка к родителю, и он может потреблять больше памяти, если ваши уровни в QuadTree различны (по количеству элементов в одном из, например, менее 2 ^ N).
Примечание: это очень редкий тип решения, и в большинстве случаев рекурсивный лучше.
Некоторые приложения могут использовать квадродерево, которое преобразуется в массив с ключом «индекс Morton». Такое четырехугольное дерево представляет собой огромный массив без каких-либо дочерних указателей.
Вы можете удалить это так же просто, как удалить массив.
Однако не все приложения могут использовать это MortonIndexed Quadtree.
Но рекурсия не должна быть проблемой, потому что у дерева квадратов не должно быть глубины больше 16. Если намного глубже, то вы используете неправильный тип дерева квадратов.
Я использую свою собственную реализацию дерева, чтобы избежать рекурсии. В моей реализации Node содержит указатель на родительский узел, дочерний узел и узел Next Plain (глубина одного уровня). Используя эти данные, легко реализовать нерекурсивную итерацию дерева.