# -*- coding: utf-8 -*-
'''
Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.8 如何找出排序二叉树上任意两个结点
的最近共同父节点
题目:
对于一棵给定的排序二叉树,求两个结点的共同父结点,例如在下图中,结点1和结点5的共同
父结点为3。
6
3 9
2 5 8 10
1 4 7
分析:
寻找公共父节点,一种简单的方法就是:
确定从根节点到第一个节点的路径path1(假设根节点为6,第一个节点为1,
则路径为: 6,3,2,1),确定从根节点到第二个节点的路径path2
(假设根节点为6,第二个节点为5,则路径为: 6,3,5)
则同事遍历path1和path2,最后一个相同的元素即为最近的公共父节点
关键:
1 书上解法
假设不是二叉排序树,而是普通的树,则需要使用递归来做,
用一个栈来存储路径
2 栈的实现
可以用数组实现
参考:
Python程序员面试算法宝典
'''
def findNearestCommonAncestor(root, findValue):
path = list()
if not root:
return False, path
if findValue is None:
return False, path
while root:
if root.data == findValue:
path.append(root.data)
return True, path
elif root.data < findValue:
path.append(root.data)
root = root.right
else:
path.append(root.data)
root = root.left
return False, path
class BinaryTreeNode(object):
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
'''
6
3 9
2 5 8 10
1 4 7
'''
def buildTree(data, rootValue):
# root = BinaryTreeNode(6)
# node1 = BinaryTreeNode(3)
# node2 = BinaryTreeNode(9)
# node3 = BinaryTreeNode(2)
# node4 = BinaryTreeNode(5)
# node5 = BinaryTreeNode(8)
# node6 = BinaryTreeNode(10)
# node7 = BinaryTreeNode(1)
# node8 = BinaryTreeNode(4)
# node9 = BinaryTreeNode(7)
nodeDict = dict()
for value in data:
node = BinaryTreeNode(value)
nodeDict[value] = node
nodeDict[6].left = nodeDict[3]
nodeDict[6].right = nodeDict[9]
nodeDict[3].left = nodeDict[2]
nodeDict[3].right = nodeDict[5]
nodeDict[9].left = nodeDict[8]
nodeDict[9].right = nodeDict[10]
nodeDict[2].left = nodeDict[1]
nodeDict[5].left = nodeDict[4]
nodeDict[8].left = nodeDict[7]
root = nodeDict[rootValue]
return root
def getCommonAncestor(path1, path2, find1, find2):
if not (find1 and find2):
return
if not (path1 and path2):
return
length1 = len(path1)
length2 = len(path2)
size = min(length1, length2)
findValue = None
for i in range(size):
if path1[i] == path2[i]:
findValue = path1[i]
return findValue
class Stack(object):
def __init__(self):
self.data = list()
def empty(self):
result = False if self.data else True
return result
def push(self, value):
self.data.append(value)
def pop(self):
if self.empty():
info = "stack is empty, it can not pop"
print info
else:
self.data.pop()
def top(self):
if self.empty():
info = "stack is empty, it can not get top element"
print info
else:
return self.data[-1]
def getPathFromRoot(root, findValue, stack):
if root is None:
return False
if root.data == findValue:
stack.push(root.data)
return True
leftFlag = getPathFromRoot(root.left, findValue, stack)
if leftFlag:
stack.push(root.data)
return True
rightFlag = getPathFromRoot(root.right, findValue, stack)
if not rightFlag:
return False
else:
# 如果node节点在root节点的左子树或者右子树上,那么root就是祖先,需要加入到栈中
stack.push(root.data)
return True
def getNearestCommonAncestor(root, child1, child2):
stack1 = Stack()
stack2 = Stack()
getPathFromRoot(root, child1, stack1)
getPathFromRoot(root, child2, stack2)
result = None
while not stack1.empty() and not stack2.empty() and stack1.top() == stack2.top():
result = stack1.top()
stack1.pop()
stack2.pop()
return result
def process():
data = [6, 3, 9, 2, 5, 8, 10, 1, 4, 7]
root = buildTree(data, data[0])
child1 = 1
child2 = 5
result = getNearestCommonAncestor(root, child1, child2)
print result
# find1, path1 = findNearestCommonAncestor(root, 1)
# find2, path2 = findNearestCommonAncestor(root, 5)
# result = getCommonAncestor(path1, path2, find1, find2)
# print result
if __name__ == "__main__":
process()
Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.8 如何找出排序二叉树上任意两个结点 的最近共同父节点
猜你喜欢
转载自blog.csdn.net/qingyuanluofeng/article/details/91788573
今日推荐
周排行