Python刷題--Tree
阿新 • • 發佈:2018-12-09
# -*- coding:UTF-8 -*-
import collections
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def maxDepth(root):
if root is None:
return 0
left = maxDepth(root.left)
right = maxDepth(root.right)
return max(left, right) + 1
def minDepth(root):
if root is None:
return 0
left = minDepth(root.left)
right = minDepth(root.right)
return min(left, right) + 1
def numOfTreeNode(root):
if root is None:
return 0
left = numOfTreeNode(root.left)
right = numOfTreeNode(root.right)
return left + right + 1
def numsOfNoChildNode(root):
if root is None:
return 0
if (root.left is None and root.right is None):
return 1
return numsOfNoChildNode(root.left) + numsOfNoChildNode(root.right)
def numsOfkLevelTreeNode(root, k):
if root is None or k < 1:
return 0
if k == 1:
return 1
numsLeft = numsOfkLevelTreeNode(root.left, k - 1)
numsRight = numsOfkLevelTreeNode(root.right, k - 1)
return numsLeft + numsRight
def isBalanced(root):
return maxDeath2(root) != -1
def maxDeath2(root):
if root is None:
return 0
left = maxDeath2(root.left)
right = maxDeath2(root.right)
if (left == -1 or right == -1 or abs(left - right) > 1):
return -1
return max(left, right) + 1
def isCompleteTreeNode(root):
if root is None:
return False
queue = collections.deque()
queue.append(root)
result = True
hasNoChild = False
while (queue):
current = queue.popleft()
if (hasNoChild):
if (current.left != None or current.right != None):
result = False
break
else:
if (current.left != None and current.right != None):
queue.append(current.left)
queue.append(current.right)
elif (current.left != None and current.right == None):
queue.append(current.left)
hasNoChild = True
elif (current.left == None and current.right != None):
result = False
break
else:
hasNoChild = True
return result
def isSameTreeNode(t1, t2):
if (t1 is None and t2 is None):
return True
elif (t1 is None or t2 is None):
return False
if (t1.val != t2.val):
return False
left = isSameTreeNode(t1.left, t2.left)
right = isSameTreeNode(t1.right, t2.right)
return left and right
def mirrorTreeNode(root):
if root is None:
return 0
left = mirrorTreeNode(root.left)
right = mirrorTreeNode(root.right)
root.left = right
root.right = left
return root
# def getLastCommonParent(root, t1, t2):
# if (findNode(root.left, t1)):
# if (findNode(root.right, t2)):
# return root
# else:
# return getLastCommonParent(root.left, t1, t2)
# else:
# if (findNode(root.left, t2)):
# return root
# else:
# return getLastCommonParent(root.right, t1, t2)
#
#
# def findNode(root, node):
# if (root is None or node is None):
# return False
# if (root == node):
# return True
# found = findNode(root.left, node)
# if (not found):
# found = findNode(root.right, node)
# return found
"""
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______6______
/ \
___2__ ___8__
/ \ / \
0 _4 7 9
/ \
3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
"""
"""注意這裡是一個二叉搜尋樹,根結點的右子樹上所有的點的值都比根結點大,左子樹上所有點的值都比根結點的值小
因此分為四種情況,
1、如果兩個節點一個值比節點大,一個小,那麼二者的公共節點肯定是根結點,
2、如果兩個節點中有一個與根結點的值同樣大,那麼二者的公共節點同樣是根結點
3、如果兩個節點的值都比根結點小,那麼二者的公共節點出現在根結點的左子樹中,遞迴查詢
4、如果兩個節點的值都比根結點大,那麼二者的公共節點出現在根結點的右子樹中,遞迴查詢
"""
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if (p.val - root.val) * (q.val - root.val) <= 0:
return root
if p.val < root.val and q.val < root.val:
return self.lowestCommonAncestor(root.left, p, q)
if p.val > root.val and q.val > root.val:
return self.lowestCommonAncestor(root.right, p, q)
# 廣度優先遍歷演算法
def level_queue(root):
if root is None:
return
my_queue = collections.deque()
node = root
my_queue.append(node)
while my_queue:
node = my_queue.popleft()
print(node.val)
if node.left is not None:
my_queue.append(node.left)
if node.right is not None:
my_queue.append(node.right)
# 深度優先遍歷演算法
def depth_tree(tree_node):
if tree_node is not None:
print(tree_node.val)
if tree_node.left is not None:
depth_tree(tree_node.left)
if tree_node.right is not None:
depth_tree(tree_node.right)
"""
二叉堆本質上是一種完全二叉樹,它分為兩個型別:
1.最大堆
2.最小堆
對於二叉堆,如下有幾種操作:
1.插入節點
2.刪除節點
3.構建二叉堆 : 本質上就是讓所有非葉子節點依次下沉。
1
/ \
3 2
/ \ / \
6 5 7 8
/\
9 10
==> 1 3 2 6 5 7 8 9 10
假設父節點的下標是parent,那麼它的左孩子下標就是 2*parent+1;它的右孩子下標就是 2*parent+2 。
舉例 小根堆:
"""
def unAdjust(array):
childIndex = len(array) - 1
parentIndex = childIndex / 2
temp = array[childIndex]
while (childIndex > 0 and temp < array[parentIndex]):
array[childIndex] = array[parentIndex]
childIndex = parentIndex
parentIndex = parentIndex / 2
array[parentIndex] = temp
def downAdjust(array, parentIndex, length):
temp = array[parentIndex]
childIndex = 2 * parentIndex + 1
while (childIndex < length):
if childIndex + 1 < length and array[childIndex + 1] < array[childIndex]:
childIndex += 1
if temp <= array[childIndex]:
break
array[parentIndex] = array[childIndex]
parentIndex = childIndex
childIndex = 2 * childIndex + 1
array[parentIndex] = temp
def buildHeap(array):
for i in range(len(array) / 2)[::-1]:
downAdjust(array, i, len(array))
if __name__ == '__main__':
root = TreeNode(0)
a = TreeNode(1)
b = TreeNode(3)
c = TreeNode(4)
d = TreeNode(5)
e = TreeNode(6)
f = TreeNode(7)
g = TreeNode(8)
root.left = a
root.right = b
a.left = c
a.right = d
c.left = e
e.right = f
e.left = g
# print maxDepth(root)
# print minDepth(root)
# print(numOfTreeNode(root))
# print(numsOfNoChildNode(root))
# print(numsOfkLevelTreeNode(root, 4))
# print(isBalanced(root))
# print(maxDeath2(root))
# print(isCompleteTreeNode(c))
# print getLastCommonParent(root, a, b)
print("##" * 20)
# level_queue(root)
# print depth_tree(root)
array = [7, 1, 3, 10, 5, 2, 8, 9, 6]
buildHeap(array)
print(array)