Как очистить Quad Tree без рекурсии (возможно, с использованием очереди?)

Хорошо, учитывая класс по линии

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 () является публичной функцией, которую вы вызываете для удаления всех узлов ниже текущего узла.

0

Решение

Есть две идеи (подходы):

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).

Примечание: это очень редкий тип решения, и в большинстве случаев рекурсивный лучше.

0

Другие решения

Некоторые приложения могут использовать квадродерево, которое преобразуется в массив с ключом «индекс Morton». Такое четырехугольное дерево представляет собой огромный массив без каких-либо дочерних указателей.
Вы можете удалить это так же просто, как удалить массив.

Однако не все приложения могут использовать это MortonIndexed Quadtree.

Но рекурсия не должна быть проблемой, потому что у дерева квадратов не должно быть глубины больше 16. Если намного глубже, то вы используете неправильный тип дерева квадратов.

0

Я использую свою собственную реализацию дерева, чтобы избежать рекурсии. В моей реализации Node содержит указатель на родительский узел, дочерний узел и узел Next Plain (глубина одного уровня). Используя эти данные, легко реализовать нерекурсивную итерацию дерева.

-1
По вопросам рекламы [email protected]