Return the level-order_ index given the root and a possible descendent. .. _level-order: https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search :return: Level-order index of the descendent relative to the root node. :rtype: int :raise binarytree.exceptions.NodeTy
(root: Node, descendent: Node)
| 2056 | |
| 2057 | |
| 2058 | def get_index(root: Node, descendent: Node) -> int: |
| 2059 | """Return the level-order_ index given the root and a possible descendent. |
| 2060 | |
| 2061 | .. _level-order: |
| 2062 | https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search |
| 2063 | |
| 2064 | :return: Level-order index of the descendent relative to the root node. |
| 2065 | :rtype: int |
| 2066 | :raise binarytree.exceptions.NodeTypeError: If root or descendent is |
| 2067 | not an instance of :class:`binarytree.Node`. |
| 2068 | :raise binarytree.exceptions.NodeReferenceError: If given a node that is |
| 2069 | not a root/descendent. |
| 2070 | |
| 2071 | **Example**: |
| 2072 | |
| 2073 | .. doctest:: |
| 2074 | |
| 2075 | >>> from binarytree import Node, get_index |
| 2076 | >>> |
| 2077 | >>> root = Node(1) |
| 2078 | >>> root.left = Node(2) |
| 2079 | >>> root.right = Node(3) |
| 2080 | >>> root.left.right = Node(4) |
| 2081 | >>> |
| 2082 | >>> get_index(root, root.left) |
| 2083 | 1 |
| 2084 | >>> get_index(root, root.right) |
| 2085 | 2 |
| 2086 | >>> get_index(root, root.left.right) |
| 2087 | 4 |
| 2088 | >>> get_index(root.left, root.right) |
| 2089 | Traceback (most recent call last): |
| 2090 | ... |
| 2091 | binarytree.exceptions.NodeReferenceError: given nodes are not in the same tree |
| 2092 | """ |
| 2093 | if root is None: |
| 2094 | raise NodeTypeError("root must be a Node instance") |
| 2095 | |
| 2096 | if descendent is None: |
| 2097 | raise NodeTypeError("descendent must be a Node instance") |
| 2098 | |
| 2099 | current_nodes: List[Optional[Node]] = [root] |
| 2100 | current_index = 0 |
| 2101 | has_more_nodes = True |
| 2102 | |
| 2103 | while has_more_nodes: |
| 2104 | has_more_nodes = False |
| 2105 | next_nodes: List[Optional[Node]] = [] |
| 2106 | |
| 2107 | for node in current_nodes: |
| 2108 | if node is not None and node is descendent: |
| 2109 | return current_index |
| 2110 | |
| 2111 | if node is None: |
| 2112 | next_nodes.append(None) |
| 2113 | next_nodes.append(None) |
| 2114 | else: |
| 2115 | next_nodes.append(node.left) |