Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1782143
  • 博文数量: 297
  • 博客积分: 285
  • 博客等级: 二等列兵
  • 技术积分: 3006
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-06 22:04
个人简介

Linuxer, ex IBMer. GNU https://hmchzb19.github.io/

文章分类

全部博文(297)

文章存档

2020年(11)

2019年(15)

2018年(43)

2017年(79)

2016年(79)

2015年(58)

2014年(1)

2013年(8)

2012年(3)

分类: Python/Ruby

2018-04-15 11:34:07

1..

is this Binary Tree a Binary Search Tree.
对于Binary Search Tree,如果使用inorder traversal, 则可以得到一个ordered list.
所以这种方法最简单:

点击(此处)折叠或打开

  1. #BST Node class
  2. class Tree_Node:
  3.     __slots__='value','left','right'
  4.     
  5.     def __init__(self, value, left=None, right=None):
  6.         self.value = value
  7.         self.left = left
  8.         self.right = right

  9. #binary search Tree: inorder traversal will get a sorted list
  10. def is_bst2(tree):
  11.     tree_values = []
  12.     
  13.     def inorder(tree):
  14.         if tree != None:
  15.             inorder(tree.left)
  16.             tree_values.append(tree.value)
  17.             inorder(tree.right)
  18.     
  19.     inorder(tree)
  20.     #print(tree_values)
  21.     return sorted(tree_values) == tree_values
另外一个思路则是使用递归,多使用两个变量,记录当前的key上限和下限,然后比较所有Node是否小于上限并且大于下限。然后左右Node递归。

点击(此处)折叠或打开

  1. #use recursion
  2. def is_bst(node, lower_lim=None, upper_lim=None):
  3.     if lower_lim is not None and node.value < lower_lim:
  4.         return False
  5.     if upper_lim is not None and upper_lim < node.value:
  6.         return False
  7.     
  8.     is_left_bst = True
  9.     is_right_bst = True
  10.     
  11.     if node.left is not None:
  12.         is_left_bst = is_bst(node.left, lower_lim, node.value)
  13.     if node.right is not None:
  14.         is_right_bst = is_bst(node.right, node.value, upper_lim)
  15.     
  16.     return is_left_bst and is_right_bst

  17. def test_is_bst():
  18.     root=Tree_Node(10)
  19.     root.left = Tree_Node(5)
  20.     root.right = Tree_Node(15)
  21.     root.right.left = Tree_Node(12)
  22.     root.right.right = Tree_Node(20)
  23.     
  24.     #root.left.right =Tree_Node(1)
  25.     
  26.     print(is_bst2(root))
  27.     print(is_bst(root))

  28. test_is_bst()

2..

print tree level

''' eg: tree below

1

/ \

2 3

/ \

4 5


will be printed as

"1

2 3

4 5"

'''


点击(此处)折叠或打开

  1. import collections
  2. def levelOrderPrint(tree):
  3.     
  4.     if tree == None:
  5.         return
  6.     nodes = collections.deque([tree])
  7.     
  8.     currentCount =1
  9.     nextCount = 0
  10.     
  11.     while len(nodes) != 0:
  12.         currentNode = nodes.popleft()
  13.         currentCount -= 1
  14.         
  15.         print(currentNode.value,end=' ')
  16.         
  17.         if currentNode.left:
  18.             nodes.append(currentNode.left)
  19.             nextCount += 1
  20.         
  21.         if currentNode.right:
  22.             nodes.append(currentNode.right)
  23.             nextCount += 1
  24.         
  25.         if currentCount == 0:
  26.             print()
  27.             currentCount, nextCount = nextCount, currentCount


  28. def test_levelOrderPrint():
  29.     root=Tree_Node(1)
  30.     root.left=Tree_Node(2)
  31.     root.right=Tree_Node(3)
  32.     root.left.left=Tree_Node(4)
  33.     root.right.right=Tree_Node(5)
  34.     
  35.     levelOrderPrint(root)


  36. test_levelOrderPrint()

3.

lowest common ancestors , assume no duplicates in the binary tree

找到两个Node 最近的共同祖先。
这个方法是从head 到两个Node的Path返回一个list,
然后从list里面开始pop,开始比较,直到发现不同的Node, break,返回最后一个相同的Node .


点击(此处)折叠或打开

  1. #lower common ancestors , no duplicates in the binary tree
  2. def lca(root, value1, value2):
  3.     path_to_value1 = path_to_x(root, value1)
  4.     path_to_value2 = path_to_x(root, value2)
  5.     [ print (i.value) for i in path_to_value1]
  6.     [ print (i.value) for i in path_to_value2]
  7.     
  8.     if path_to_value1 is None or path_to_value2 is None:
  9.         return None
  10.         
  11.     lca_to_return = None
  12.     
  13.     
  14.     while len(path_to_value1) !=0 and len(path_to_value2)!=0:
  15.         value1_pop = path_to_value1.pop()
  16.         value2_pop = path_to_value2.pop()
  17.         if value1_pop == value2_pop:
  18.             lca_to_return = value1_pop
  19.         else:
  20.             break
  21.     
  22.     return lca_to_return
  23.     

  24. #return a list from node to x
  25. def path_to_x(root, x):
  26.     
  27.     if root is None:
  28.         return None
  29.     
  30.     if root.value == x:
  31.         return [root]
  32.         
  33.     left_path = path_to_x(root.left, x)
  34.     if left_path is not None:
  35.         left_path.append(root)
  36.         return left_path
  37.     
  38.     right_path = path_to_x(root.right, x)
  39.     if right_path is not None:
  40.         right_path.append(root)
  41.         return right_path
  42.     
  43.     return None
  44.     

  45. def test_lca():
  46.     ''' Tree like this
  47.                      5(head)
  48.                    / \
  49.                  1 4
  50.                / \ / \
  51.               3 8 9 2
  52.              / \
  53.             6 7
  54.     lca(head, 8, 7) -> return 1
  55.     '''
  56.     
  57.     head = Tree_Node(5)
  58.     head.left = Tree_Node(1)
  59.     head.left.left= Tree_Node(3)
  60.     head.left.right = Tree_Node(8)
  61.     head.left.left.left = Tree_Node(6)
  62.     head.left.left.right =Tree_Node(7)
  63.     head.right= Tree_Node(4)
  64.     head.right.left = Tree_Node(9)
  65.     head.right.right = Tree_Node(2)
  66.     
  67.     ret = lca(head, 8, 7)
  68.     if ret:
  69.         print(ret.value)
  70.     
  71. test_lca()

4..
修剪一个BST, 提供一个最小值和一个最大值,返回值在其中的Node,并且仍然保留BST的特性。

点击(此处)折叠或打开

  1. '''
  2. Given the root of a binary search Tree and 2
  3. numbers min and max, trim the tree such that all the numbers in the new tree
  4. are between min and max (inclusive),The resulting tree should still be a valid
  5. binary search Tree.
  6. eg:
  7.              8
  8.            / \
  9.           3 10
  10.          / \ \
  11.         1 6 14
  12.            / \ /
  13.           4 7 13

  14. min=5, max=13

  15. will get resulting BST:

  16.               8
  17.             / \
  18.            6 10
  19.             \ \
  20.              7 13
  21. '''


  22. def trim_bst(tree,min_value, max_value):
  23.     #use postorder traversal

  24.     if tree == None:
  25.         return None
  26.     
  27.     tree.left = trim_bst(tree.left, min_value, max_value)
  28.     tree.right = trim_bst(tree.right, min_value, max_value)
  29.     
  30.     if min_value <= tree.value <= max_value:
  31.         return tree
  32.     
  33.     if tree.value < min_value:
  34.         return tree.right
  35.     
  36.     if tree.value > max_value:
  37.         return tree.left

  38. def inorder_traversal(root):
  39.     
  40.     if root is None:
  41.         return
  42.     else:
  43.         inorder_traversal(root.left)
  44.         print(root.value)
  45.         inorder_traversal(root.right)
  46.         
  47.     
  48.     
  49. def test_trim_bst():
  50.     root=Tree_Node(8)
  51.     root.left= Tree_Node(3)
  52.     root.left.left = Tree_Node(1)
  53.     root.left.right=Tree_Node(6)
  54.     root.left.right.left = Tree_Node(4)
  55.     root.left.right.right = Tree_Node(7)
  56.     
  57.     root.right=Tree_Node(10)
  58.     root.right.right= Tree_Node(14)
  59.     root.right.right.left = Tree_Node(13)
  60.     
  61.     
  62.     trim_bst(root, 5, 13)
  63.     
  64.     #inorder traversal will get sorted output
  65.     #inorder_traversal(root)
  66.     
  67.     
  68.     levelOrderPrint(root)
  69.     
  70.     
  71. #test_trim_bst()


阅读(838) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~