А потом появляются программы, которые не освобождают ресурсы, используют память так, что кэш процессоров становится бесполезен, половину процессорного времени тратят на переключение контекста и т.д. и т.п.
Эрнэст Фарукшин, конкурентное выполнение недетерминированно. Если JMM что-то не гарантирует, то это может произойти, а может и не произойти. Никого не устроит программа, которая работает случайным образом в разные моменты времени, поэтому программист должен самостоятельно заботиться о синхронизации.
Вячеслав Осипов, дерево - это частный случай ациклического графа. Выберите удобную вам структуру для дерева. Так как граф неориентированный, просто берите произвольную вершину и начинайте обход, складывая вершины в выбранную структуру. В конце обхода в этой структуре будет дерево. Правда, не обязательно сбалансированное.