ds之树

数据结构的树

题目

给予一个二叉树的根节点,验证该树是否是二叉树搜索树,在O(n)时间内。

分析与解答

二叉搜索树是一种特殊的二叉树

它满足如下的条件:

  • 结点的左子树所有结点的值都小于等于该结点的值。
  • 结点的右子树所有结点的值都大于该结点的值。
  • 结点的左右子树同样都必须是二叉搜索树。

也就是说

  • 任何一个节点的key值都比它左子树上的节点的key值要大,但是比它右子树上的key值要小。
  • 节点查找、插入、删除等操作的时间复杂度都是O(logn)

主要的一个特点 就是中序遍历一棵树 会得到一个递增的序列

在此题目的条件是給出一个根节点

简化起见 考虑简单的情况

即是給出的二叉树形式为列表的形式 顺序为前序 也就是一个元素就是根节点

比如

[5,1,4,#,#,3,6] 这个是給出的二叉树 根节点为第一个元素 也就是5

注意一下 实际上在 python 当中給出的应该是这样的列表

[5, 1, 4, None, None, 3, 6]

1
2
3
4
5
6
7
8
9
10
11
12
def traverse_binary_tree(node, callback):
if node is None:
return
traverse_binary_tree(node.leftChild, callback)
callback(node.value)
traverse_binary_tree(node.rightChild, callback)


def get_inorder_traversal(root):
result = []
traverse_binary_tree(root, lambda element: result.append(element))
return result

解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution1(object):

def valid_bst(self, root):
# 直接先中序遍历 得到序列
def inorder_traversal(root):
if root is None:
return []
res = []
res += inorder_traversal(root.left)
res.append(root.val)
res += inorder_traversal(root.right)
return res

# 根据中序遍历的结果进行比对
return (inorder_traversal(root) == sorted(list(set(inorder_traversal(root)))))

另外也可以依次比较左右子树各个子节点的值 保证 左 < zhong < 右

1
2
3
4
5
6
7
8
9
10
11
class Solution2(object):

def valid_bst(self, root):
return self.helper(root, -2**64, 2**64-1)

def helper(self, root, left, right):
if root is None:
return True
if left >= root.val or right <= root.val:
return False
retun self.helper(root.left, left, root.val) and self.helper(root.right, root.val, right)

工程化的项目当中 一般是测试先行 也就是说需要先把测试用例这些东西准备好

在此 为了完善起见 肯定是需要补上测试用例的

能跑过测试 说明代码是正确的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class Node(object):

def __init__(self, x):
self.val = x
self.left = None
self.right = None

def get_val(self):
return self.val

def dict_form(self):
dict_set = {
"val": self.val,
"left": self.left,
"right": self.right,
}
return dict_set

def __str__(self):
return str(self.val)


class Tree(object):

def __init__(self, data_list):
# 初始化即将传入的列表的迭代器
self.root = data_list[0] if data_list else None
self.it = iter(data_list)

def create_tree(self, bt=None):
try:
# 获取下一个元素
next_data = next(self.it)
# 如果当前列表元素为 "#", 则认为其为 None
if next_data == '#' or next_data is None:
bt = None
else:
bt = Node(next_data)
bt.left = self.create_tree(bt.left)
bt.right = self.create_tree(bt.right)
except Exception as e:
print(e)

return bt

# 前序遍历
def preorder_traverse(self, bt):
if bt is not None:
print(bt.val, end=" ")
self.preorder_traverse(bt.left)
self.preorder_traverse(bt.right)

# 中序遍历
def inorder_traverse(self, bt):
if bt is not None:
self.inorder_traverse(bt.left)
print(bt.val, end=" ")
self.inorder_traverse(bt.right)

# 后序遍历
def postorder_traverse(self, bt):
if bt is not None:
self.postorder_traverse(bt.left)
self.postorder_traverse(bt.right)
print(bt.val, end=" ")

# 综合打印
def print_traverse(self, bt):
print("前序遍历: ", end="")
self.preorder_traverse(bt)
print('\n')
print("中序遍历: ", end="")
self.inorder_traverse(bt)
print('\n')
print("后序遍历: ", end="")
self.postorder_traverse(bt)
print('\n')


if __name__ == "__main__":
data_list = list("124#7###35##68###")
btree = Tree(data_list)
root = btree.create_tree()
btree.print_traverse(root)

首先可以运行tests.py 文件 里面暂时只放了6个测试用例 可以看到是通过的

本次 运行环境为 python3.5

当然工程环境下可能有上百个以上的测试用例