Предполагая, что селектор дает дочерние узлы, ваш второй метод - это обход "сначала справа первой глубины". То есть если бы у вас было
A
/ \
B C
/ \ / \
D E F G
Затем вы получаете A, C, G, F, B, E, D. Вы получаете «G» перед «B», потому что «сначала глубина» идет настолько глубоко, насколько это возможно, прежде чем пробует другую ветвь. В вашем конкретном примере вы получите C перед B, потому что он расставляет приоритеты справа налево.
Если вы изменили его на
foreach (var item in items.Reverse())
тогда вы получите обход влево-вглубь-в-первых, как большинство людей думают о обходе в глубину-в-первых.
Если вы измените стек на очередь, он станет обходом в ширину. A, B, C, D, E, F, G. Вы делаете целый "уровень" за один раз.
Есть и другие обходы. Обратите внимание, что оба поиска в глубину и в ширину имеют свойство, что родительские узлы располагаются перед дочерними узлами. У вас также могут быть обходы «после заказа», при которых каждый узел идет после своих потомков.
Бинарные деревья также имеют обход "inorder". Обход этого дерева по порядку - это D, B, E, A, F, C, G. То есть, каждый левый ребенок предшествует всем своим предкам, а каждый правый ребенок идет после всех своих предков. Как упражнение, вы можете написать порядок обхода в двоичном дереве?