Предположим, у вас есть плоская таблица, в которой хранится иерархия упорядоченного дерева:
Id Name ParentId Order
1 'Node 1' 0 10
2 'Node 1.1' 1 10
3 'Node 2' 0 20
4 'Node 1.1.1' 2 10
5 'Node 2.1' 3 10
6 'Node 1.2' 1 20
Вот схема, где мы имеем [id] Name. Корневой узел 0 вымышленный.
[0] ROOT
/ \
[1] Узел 1 [3] Узел 2
/ \ \
[2] Узел 1.1 [6] Узел 1.2 [5] Узел 2.1
/
[4] Узел 1.1.1
Какой минималистический подход вы бы использовали для вывода этого в HTML (или текст, если на то пошло) как правильно упорядоченное, правильно отступающее дерево?
Предположим далее, что у вас есть только базовые структуры данных (массивы и хэш-карты), нет причудливых объектов со ссылками родитель / потомок, нет ORM, нет фреймворка, только ваши две руки. Таблица представлена в виде набора результатов, к которому можно получить произвольный доступ.
Псевдокод или простой английский в порядке, это чисто концептуальный вопрос.
Бонусный вопрос: существует ли принципиально лучший способ хранить древовидную структуру, подобную этой, в СУБД?
ИЗМЕНЕНИЯ И ДОПОЛНЕНИЯ
Чтобы ответить на вопрос одного комментатора ( Марка Бесси ): корневой узел не нужен, потому что он все равно никогда не будет отображаться. ParentId = 0 - это соглашение для выражения «это верхний уровень». Столбец «Порядок» определяет порядок сортировки узлов с одним и тем же родителем.
«Набор результатов», о котором я говорил, можно представить в виде массива хэш-карт (чтобы остаться в этой терминологии). Для моего примера должно было быть уже там. Некоторые ответы проходят лишнюю милю и сначала ее строят, но это нормально.
Дерево может быть сколь угодно глубоким. Каждый узел может иметь N детей. Хотя я не имел в виду дерево «миллионов записей».
Не путайте мой выбор имен узлов ('Node 1.1.1') с тем, на что можно положиться. С таким же успехом узлы можно было бы назвать «Фрэнк» или «Боб», структура имен не подразумевалась, это было сделано лишь для того, чтобы сделать его читаемым.
Я опубликовал свое собственное решение, чтобы вы, ребята, могли разобрать его на части.