definition from
    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.192.8615&rep=rep1&type=pdf

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.experimental.euler_tour_tree_avl import *  # NOQA
        >>> edges = [
        >>>     ('R', 'A'), ('R', 'B'),
        >>>     ('B', 'C'), ('C', 'D'), ('C', 'E'),
        >>>     ('B', 'F'), ('B', 'G'),
        >>> ]
        >>> G = nx.Graph(edges)
        >>> node = list(G.nodes())[0]
        >>> et1 = euler_tour(G, node)
        >>> et2 = euler_tour_dfs(G, node)

def euler_tour(G, node=None, seen=None, visited=None):
    """
    definition from
    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.192.8615&rep=rep1&type=pdf

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.experimental.euler_tour_tree_avl import *  # NOQA
        >>> edges = [
        >>>     ('R', 'A'), ('R', 'B'),
        >>>     ('B', 'C'), ('C', 'D'), ('C', 'E'),
        >>>     ('B', 'F'), ('B', 'G'),
        >>> ]
        >>> G = nx.Graph(edges)
        >>> node = list(G.nodes())[0]
        >>> et1 = euler_tour(G, node)
        >>> et2 = euler_tour_dfs(G, node)
    """
    if node is None:
        node = next(G.nodes())
    if visited is None:
        assert nx.is_tree(G)
        visited = []
    if seen is None:
        seen = set([])
    visited.append(node)
    for c in G.neighbors(node):
        if c in seen:
            continue
        seen.add(c)
        euler_tour(G, c, seen, visited)
        visited.append(node)
    return visited