class TreeNode():
def __init__(self,data=-1):
self.data = data
self.left = None
self.right = None
class Tree():
def preOrder_recursion(self,root):
if not root:
return root
print root.data
self.preOrder_recursion(root.left)
self.preOrder_recursion(root.right)
def preOrder_stack(self,root):
if not root:
return
tstack = []
node = root
while tstack or node:
while node:
print node.data
tstack.append(node)
node = node.left
node = tstack.pop()
node = node.right
a = TreeNode(9)
b = TreeNode(5)
c = TreeNode(13)
d = TreeNode(4)
e = TreeNode(6)
f = TreeNode(12)
g = TreeNode(15)
a.left = b
a.right = c
b.left = d
b.right = e
c.left = f
c.right = g
t = Tree()
t.preOrder_stack(a)
9
5
4
6
13
12
15
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回
前序+中序=二叉排序树(让前序\后序拥有中序的索引,依此构建二叉树)
思路解释:前序(根左右),中序(左根右,左孩子序号小于根,右孩子大于根)。
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution1:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
if len(pre) == 0:
return None
elif len(pre) == 1:
return TreeNode(pre[0])
else:
#从前序中选一个元素
troot = TreeNode(pre[0])
#构建左子树:在中序索引中(从0开始)找到该元素,左孩子共有(下标个元素),从前序中从前往后筛选“下标”个元素,即为左孩子序列
# python中的List切片,为前闭后开。
troot.left = self.reConstructBinaryTree(pre[1:tin.index(pre[0])+1],tin[:tin.index(pre[0])])
#右孩子为前序中排除左孩子的剩余元素
troot.right = self.reConstructBinaryTree(pre[tin.index(pre[0])+1:],tin[tin.index(pre[0])+1:])
return troot
if __name__ == '__main__':
s = Solution1()
print s.reConstructBinaryTree([1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6])
<__main__.TreeNode instance at 0x0000000003CCA248>
a=[1,2,3]
print a.index(3)
print a[0:1]
2
[1]
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
考察清楚哪些情况会引入空指针,并进行处理。
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
if not pRoot1 or not pRoot2:
return False
return self.checktree(pRoot1,pRoot2) or self.HasSubtree(pRoot1.left,pRoot2) or self.HasSubtree(pRoot1.right,pRoot2)
def checktree(self,A,B):
if not B:
return True
if not A or A.val!=B.val:
return False
return self.checktree(A.left,B.left) and self.checktree(A.right,B.right)
操作给定的二叉树,将其变换为源二叉树的镜像。
二叉树的遍历
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回镜像树的根节点
def Mirror(self, root):
# write code here
if root != None:
root.left,root.right = root.right,root.left
self.Mirror(root.left)
self.Mirror(root.right)
return root
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
二叉树的遍历,队列,BFS(广度优先搜索)
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
# 返回从上到下每个节点值列表,例:[1,2,3]
def PrintFromTopToBottom(self, root):
# write code here
if not root:
return []
l = []
q = [root]
print q #添加的为treenode节点
while q:
temp = q.pop(0)
l.append(temp.val)
if temp.left:
q.append(temp.left)
if temp.right:
q.append(temp.right)
return l
t = TreeNode(12)
t.left = TreeNode(3)
t.right = TreeNode(4)
s = Solution()
print s.PrintFromTopToBottom(t)
[<__main__.TreeNode instance at 0x0000000003C88488>]
[12, 3, 4]
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同
二叉搜索树,后序遍历
# -*- coding:utf-8 -*-
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
if not sequence:
return False
seqLen = len(sequence)
if seqLen == 1:
return True
tempRoot = sequence[-1]
k = 0
# 注意不是for循环
while sequence[k]<tempRoot:
k += 1
for i in range(k,seqLen-1):
if sequence[i]<tempRoot:
return False
leftTree = sequence[:k]
rightTree = sequence[k:seqLen-1]
leftIcon = True
rightIcon = True
# 递归判断
if len(leftTree):
leftIcon = self.VerifySquenceOfBST(leftTree)
if len(rightTree):
rightIcon = self.VerifySquenceOfBST(rightTree)
return leftIcon and rightIcon
s = Solution()
s.VerifySquenceOfBST([12,3,5,7,17,19])
False
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
前序遍历、栈
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二维列表,内部每个列表表示找到的路径
def FindPath(self, root, expectNumber):
# write code here
if not root:
return []
if not root.left and not root.right and root.val==expectNumber:
return [[root.val]]
pathlist = []
temp = []
left = self.FindPath(root.left,expectNumber-root.val)
right = self.FindPath(root.right,expectNumber-root.val)
for i in left+right:
pathlist.append([root.val]+i)
return pathlist
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度
# 递归
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def TreeDepth(self, pRoot):
# write code here
if not pRoot:
return 0
if pRoot.left == None and pRoot.right ==None:
return 1
left = self.TreeDepth(pRoot.left)
right = self.TreeDepth(pRoot.right)
return max(left,right)+1
# 借助collections模块中定义的新数据类型deque(双向列表)
class Solution:
def TreeDepth(self, pRoot):
# write code here
if not pRoot:
return 0
from collections import deque
dq = deque()
layer = 1
# 插入时设置下标,输出时也可同时得到下标
dq.append((pRoot,1))
while dq:
# 同时得到元素和下标
node, layer = dq.popleft()
deep = layer
if node.left:
#插入时设置下标,相对其父节点增加1(代表深度)
dq.append((node.left,layer+1))
if node.right:
#插入时设置下标,相对其父节点增加1(代表深度),此时左右孩子下标相同
dq.append((node.right,layer+1))
return deep
# 无需借助其他模块(时间同上面差不多)
class Solution:
def TreeDepth(self, pRoot):
# write code here
if not pRoot:
return 0
a=[pRoot]
d=0
while a: # 存储当前轮,存储树的某一层的所有节点
b=[] # 存储下一轮,树的某一层的所有节点
for node in a:
if node.left:
b.append(node.left)
if node.right:
b.append(node.right)
a=b
d=d+1
return d
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
利用‘树的深度方法’,若每个节点的左右子树深度相差不超过1即可。
#后序遍历,递归判断子节点的深度
# -*- coding:utf-8 -*-
class Solution:
def IsBalanced_Solution(self, pRoot):
# write code here
if not pRoot:
return True
if abs(self.Tree_Depth(pRoot.left)-self.Tree_Depth(pRoot.right))>1:
return False
return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
def Tree_Depth(self,pRoot):
if not pRoot:
return 0
left = self.Tree_Depth(pRoot.left)
right = self.Tree_Depth(pRoot.right)
return max(left+1,right+1)
#后序遍历,递归判断子树是否平衡
class Solution:
def IsBalanced_Solution(self, pRoot):
# write code here
return self.TreeDepth(pRoot) !=-1
def TreeDepth(self,root):
if not root:
return 0
left = self.TreeDepth(root.left)
if left == -1 :
return -1
right = self.TreeDepth(root.right)
if right == -1:
return -1
return -1 if abs(left-right)>1 else 1+max(left,right)
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
中序遍历:左根右,所以下一个结点要从找右子树出发。(另外注意:结点只多了指向‘父结点’的指针,即.next是指向父结点)所以可以分为如下几种情况:
# -*- coding:utf-8 -*-
# class TreeLinkNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# self.next = None
class Solution:
def GetNext(self, pNode):
# write code here
if not pNode:
return None
# 若该结点有右子树,返回右子树的最左边结点
if (pNode.right!=None):
pNode = pNode.right
while (pNode.left!=None):
pNode = pNode.left
return pNode
# 若该结点无右子树,即为左孩子/右孩子。
while (pNode.next!=None):
# 若该结点为左孩子,返回其父结点。
if pNode.next.left==pNode:
return pNode.next
# 若该结点为右孩子,返回其父结点的父结点
pNode = pNode.next
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
对称的含义:根结点的左右子树同,左子树的左子树和右子树的右子树相同。左子树的右子树和右子树的左子树相同。(镜像)
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetrical(self, pRoot):
# write code here
if not pRoot:
return True
return self.compare(pRoot.left,pRoot.right)
def compare(self,left,right):
if left==None:
return right==None
if right==None:
return False
if left.val!=right.val:
return False
return self.compare(left.left,right.right) and self.compare(left.right,right.left)
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
利用队列,层序遍历二叉树;利用布尔值,控制存入结点的顺序(从左到右存/从右往左)
class Solution:
def Print(self, pRoot):
# write code here
if not pRoot:
return []
from collections import deque
# res:存储最终结果;tmp:存储每行结点的值;
res,tmp=[],[]
last=pRoot
q=deque([pRoot])
left_to_right=True
while q:
t=q.popleft()
tmp.append(t.val)
if t.left:
q.append(t.left)
if t.right:
q.append(t.right)
# 若遍历到一曾的最右侧结点,则存储该行所有结点值
if t == last:
res.append(tmp if left_to_right else tmp[::-1])
left_to_right= not left_to_right
tmp=[]
#为是否开始存储该行元素做准备
if q:last=q[-1]
return res
借助队列deque遍历二叉树,每遍历完一层(!如何判断),以一个列表形式存入结果列表。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
from collections import deque
class Solution:
# 返回二维列表[[1,2],[4,5]]
def Print(self, pRoot):
# write code here
if not pRoot:
return []
q = deque([pRoot])
res,tmp = [],[]
last = pRoot
while q:
t = q.popleft()
tmp.append(t.val)
if t.left:
q.append(t.left)
if t.right:
q.append(t.right)
# 判断是否遍历完当前层
if t==last:
res.append(tmp)
tmp = []
if q: last=q[-1]
return res
class Solution:
# 返回二维列表[[1,2],[4,5]]
def Print(self, pRoot):
# write code here
if not pRoot:
return []
# res存储最终的结果
res=[]
# q存储每层的结点
q=[pRoot]
while q:
#size控制是否为同一层
size=len(q)
# row存储每层结点的值
row=[]
for i in q:
row.append(i.val)
res.append(row)
for i in range(size):
node=q.pop(0)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return res
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
flag = -1
def Serialize(self, root):
s = ""
s = self.recursionSerialize(root, s)
return s
def recursionSerialize(self, root, s):
if (root is None):
s = '$,'
return s
s = str(root.val) + ','
left = self.recursionSerialize(root.left, s)
right = self.recursionSerialize(root.right, s)
s += left + right
return s
def Deserialize(self, s):
self.flag += 1
l = s.split(',')
#递归控制条件
if (self.flag >= len(s)):
return None
root = None
if (l[self.flag] != '$'):
root = TreeNode(int(l[self.flag]))
root.left = self.Deserialize(s)
root.right = self.Deserialize(s)
return root
给定一颗二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
思路:二叉搜索树按照中序遍历的顺序打印出来正好就是排序好的顺序。所以,按照中序遍历顺序找到第k个结点就是结果。
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回对应节点TreeNode
def KthNode(self, pRoot, k):
# write code here
global result
result=[]
self.midnode(pRoot)
if k<=0 or len(result)<k:
return None
else:
return result[k-1]
def midnode(self,root):
if not root:
return None
self.midnode(root.left)
result.append(root)
self.midnode(root.right)
# 上下方法时间差不多,上面稍快
class Solution:
# 返回对应节点TreeNode
def KthNode(self, pRoot, k):
if pRoot==None or k==0:
return None
n=self.isorder(pRoot)
if len(n)<k:
return None
else:
return n[k-1]
def isorder(self,pRoot):
re=[]
if not pRoot:
return None
if pRoot.left:
re.extend(self.isorder(pRoot.left))
re.append(pRoot)
if pRoot.right:
re.extend(self.isorder(pRoot.right))
return re
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
直接调用内置函数sort进行排序,然后判断数组个数的奇偶,切片求出中位数。
class Solution:
def __init__(self):
self.data=[]
def Insert(self, num):
# write code here
self.data.append(num)
self.data.sort()
def GetMedian(self,data):
# write code here
length=len(self.data)
if length%2==0:
return (self.data[length//2]+self.data[length//2-1])/2.0
else:
return self.data[int(length//2)]