|
| 1 | +## Inverview-8:二叉树中序遍历的下一个节点 |
| 2 | + |
| 3 | +**题目**:给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左、右子节点的指针,还有一个指向父节点的指针。这颗二叉树如下图所示: |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +1. 如果一个节点有右子树,那么它的下一个节点就是它的右子树中的最左子节点。 |
| 8 | + |
| 9 | +2. 如果节点没有右子树的情形,并且该节点是它父节点的左子节点,那么它的下一个节点就是它的父节点。 |
| 10 | + |
| 11 | +3. 如果一个节点既没有右子树,并且它还是它父节点的右子节点,那么这种情形就比较复杂。我们可以沿着指向父节点的指针一直向上遍历,直到找到一个是它父节点的左子节点的节点。如果这样的节点存在,那么这 |
| 12 | + 个节点的父节点就是我们要找的下一个节点。 |
| 13 | + |
| 14 | + 例如 i 节点,我们沿着指向父节点的指针向上遍历,先到达节点 e。由于节点 e 是它父节点 b 的右节点,我们继续向上遍历到达节点 b。节点 b 是它父节点 a 的左子节点,因此节点 b 的父节点 a 就是节点i的下一个节点。 |
| 15 | + |
| 16 | +```python |
| 17 | + |
| 18 | +## 创建二叉树类 |
| 19 | +class Node(): |
| 20 | + def __init__(self, item): |
| 21 | + self.element = item |
| 22 | + self.parentNode = None |
| 23 | + self.leftNode = None |
| 24 | + self.rightNode = None |
| 25 | + |
| 26 | +## 构建二叉树 |
| 27 | +def struct_tree(pre_list, middle_list): |
| 28 | + |
| 29 | + if len(pre_list) == 2: |
| 30 | + |
| 31 | + # 根节点 |
| 32 | + node = Node(pre_list[0]) |
| 33 | + #左叶子节点 |
| 34 | + if pre_list[0] == middle_list[1]: |
| 35 | + left_node = Node(pre_list[1]) |
| 36 | + node.leftNode = left_node |
| 37 | + else: |
| 38 | + # 右叶子节点 |
| 39 | + right_node = Node(pre_list[1]) |
| 40 | + node.rightNode = right_node |
| 41 | + |
| 42 | + ## 添加父节点 |
| 43 | + if node.leftNode != None: |
| 44 | + node.leftNode.parentNode = node |
| 45 | + if node.rightNode != None: |
| 46 | + node.rightNode.parentNode = node |
| 47 | + |
| 48 | + return node |
| 49 | + else: |
| 50 | + ## 递归调用 |
| 51 | + for i in range(len(middle_list)): |
| 52 | + if middle_list[i] == pre_list[0]: |
| 53 | + middle_root_index = i |
| 54 | + |
| 55 | + # 根节点 |
| 56 | + node = Node(pre_list[0]) |
| 57 | + # 左子树 |
| 58 | + if middle_root_index > 1: |
| 59 | + left_pre_list = pre_list[1 : middle_root_index + 1] |
| 60 | + left_middle_list = middle_list[0 : middle_root_index] |
| 61 | + node.leftNode = struct_tree(left_pre_list, left_middle_list) |
| 62 | + elif middle_root_index == 1: |
| 63 | + left_node = Node(middle_list[0]) |
| 64 | + node.leftNode = left_node |
| 65 | + |
| 66 | + # 右子树 |
| 67 | + if middle_root_index < len(pre_list) - 2: |
| 68 | + right_pre_list = pre_list[middle_root_index + 1 : ] |
| 69 | + right_middle_list = middle_list[middle_root_index + 1 : ] |
| 70 | + node.rightNode = struct_tree(right_pre_list, right_middle_list) |
| 71 | + elif middle_root_index == len(pre_list) - 2: |
| 72 | + right_node = Node(middle_list[len(pre_list) - 1]) |
| 73 | + node.rightNode = right_node |
| 74 | + |
| 75 | + ## 添加父节点 |
| 76 | + if node.leftNode != None: |
| 77 | + node.leftNode.parentNode = node |
| 78 | + if node.rightNode != None: |
| 79 | + node.rightNode.parentNode = node |
| 80 | + |
| 81 | + return node |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | +pre_list = ['a', 'b', 'd', 'e', 'h', 'i', 'c', 'f', 'g'] |
| 86 | +middle_list = ['d', 'b', 'h', 'e', 'i', 'a', 'f', 'c', 'g'] |
| 87 | +node = struct_tree(pre_list, middle_list) |
| 88 | + |
| 89 | +## start 查找下一个节点 |
| 90 | +def next_node(current_node): |
| 91 | + input_element = current_node.element |
| 92 | + |
| 93 | + ## 第一种情况 |
| 94 | + if current_node.rightNode != None: |
| 95 | + current_node = current_node.rightNode |
| 96 | + while current_node.leftNode != None: |
| 97 | + current_node = current_node.leftNode |
| 98 | + else: |
| 99 | + print(input_element, '在中序遍历序列中的下一个节点是:', current_node.element) |
| 100 | + |
| 101 | + ## 第二种情况 |
| 102 | + elif current_node.rightNode == None and current_node is current_node.parentNode.leftNode: |
| 103 | + print(input_element, '在中序遍历序列中的下一个节点是:', current_node.parentNode.element) |
| 104 | + |
| 105 | + ## 第三种情况 |
| 106 | + elif current_node.rightNode == None and current_node is current_node.parentNode.rightNode: |
| 107 | + current_node = current_node.parentNode |
| 108 | + while not (current_node is current_node.parentNode.leftNode): |
| 109 | + current_node = current_node.parentNode |
| 110 | + else: |
| 111 | + print(input_element, '在中序遍历序列中的下一个节点是:', current_node.parentNode.element) |
| 112 | + |
| 113 | + |
| 114 | +current_node = node.leftNode |
| 115 | +print('中序遍历序列', middle_list) |
| 116 | +next_node(current_node) |
| 117 | +``` |
| 118 | + |
| 119 | +中序遍历序列 ['d', 'b', 'h', 'e', 'i', 'a', 'f', 'c', 'g'] |
| 120 | + |
| 121 | +b 在中序遍历序列中的下一个节点是: h |
| 122 | + |
| 123 | +**Inverview-8测试用例** |
| 124 | + |
| 125 | +```python |
| 126 | +print('中序遍历序列', middle_list) |
| 127 | + |
| 128 | +## 节点是没有右子树,但它是父节点的左子节点 |
| 129 | +current_node = node.leftNode.leftNode |
| 130 | +next_node(current_node) |
| 131 | + |
| 132 | +## 节点是没有右子树,但它是父节点的右子节点 |
| 133 | +current_node = node.leftNode.rightNode.rightNode |
| 134 | +next_node(current_node) |
| 135 | +``` |
| 136 | + |
| 137 | +中序遍历序列 ['d', 'b', 'h', 'e', 'i', 'a', 'f', 'c', 'g'] |
| 138 | + |
| 139 | +d 在中序遍历序列中的下一个节点是: b |
| 140 | + |
| 141 | +i 在中序遍历序列中的下一个节点是: a |
| 142 | + |
| 143 | +> 作者:[@mantchs](https://github.com/NLP-LOVE/ML-NLP) |
| 144 | +> |
| 145 | +> GitHub:[https://github.com/NLP-LOVE/CodingInterviews2-ByPython](https://github.com/NLP-LOVE/CodingInterviews2-ByPython) |
| 146 | +> |
| 147 | +> 有意向一起完成此项目或者有问题、有补充的可以加入《剑指offer》讨论群【818185620】<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=8c188e86e0eac4a214861c2c706a9c0baf75176e16e52f07b8a64d1a13f99a0d"><img border="0" src="http://pub.idqqimg.com/wpa/images/group.png" alt="《剑指offer》讨论群" title="《剑指offer》讨论群"></a> |
0 commit comments