Для дерева чаще всего удобен список смежностей. Или, если явно задано паренты и чилды, у каждого узла есть массив (или список) чилдов, иногда можно хранить ссылку на родительский узел, в зависимости от задачи. Матрица смежностей бесполезна и даже вредна, поскольку она требует O(N^2) памяти и времени работы при N узлах, а у дерева всего N-1 ребер. Для чего может понадобиться список/матрица ребер в случае деревьев, тоже не совсем понятно.
Отдельный часто используемый вид деревьев - двоичное дерево, когда есть не просто равноправные "чилды", а "правый" и "левый" чилд, т.е. вместо списка будут две явно заданные ссылки.
Двоичное дерево из пункта Д2 можно разместить в массиве, потому что оно удачно заполнено (см. описание в ответе
Wataru). Зачем нужно? Супер-экономное использование памяти - хранятся только значения узлов, но не нужно хранить ссылки и вообще создавать узлы. Если узел лежит в ячейке
arr[i], то его левый чилд - в ячейке
arr[2i + 1], правый - в
arr[2i + 2], а парент - в
arr[floor((i - 1) / 2)]. То есть мгновенный доступ к чилдам и паренту. Подробнее
здесь и
здесь
Разные древовидные структуры позволяют быстрее и легче получать доступ к данным
зависит от ситуации, от алгоритма. Где-то хорош список, где-то массив, где-то дерево - надо выбирать инструмент под задачу. Идеальной для всех случаев структуры данных нет.