A bit of additional information for those who stumbled upon this old question just like me.
As the OP writes, clr.tree_.feature returns nodes / leaves in sequential order as a depth search algorithm. First it starts with the root of the node, and then follows the left children until it reaches a leaf (encoded with -2), when it reaches a leaf, it goes up the tree from leaf to leaf until it reaches node. once it reaches node, it again descends into the hierarchy until it reaches the node leaf.
Looking at the OP example, the root of node is function 8, which has a left child, function 9. Then, if we go down the hierarchy, we will immediately reach the leaf node. Therefore, we begin to rise until we reach the non-leaf node. The next node (the right child) is also a leaf node (function 9 of two children is both leaf nodes), and then climbing up the tree, we again get function 9 at the first level of the hierarchy. Here function 9 has a left child 4, which has a leaf node as its left child, then we look at function 4 of the right child, which again is function 9, etc.
source share