包括递归方式和非递归方式
class TreeNode():
def __init__(self,value):
self.value = value
self.right = None
self.left = None
递归模式
def preOrderRecur(root):
if not root:
return
print(root.value, end=" ")
preOrderRecur(root.left)
preOrderRecur(root.right)
def inOrderRecur(root):
if not root:
return
preOrderRecur(root.left)
print(root.value, end=" ")
preOrderRecur(root.right)
def posOrderRecur(root):
if not root:
return
preOrderRecur(root.left)
print(root.value, end=" ")
preOrderRecur(root.right)
非递归 使用stack
前序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKu26FxM-1588470251314)(attachment:image.png)]
中序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PebuVpmY-1588470251320)(attachment:image.png)]
def preOrderRecur(root):
# 前序 中左右
if not root:
return
stack = [root]
while stack:
tmp = stack.pop()
print(tmp.value)
if tmp.right:
stack.append(tmp.right)
if tmp.left:
stack.append(tmp.left)
def inOrderRecur(root):
# 先压入所有左边界,再弹出最左边的节点, 左中右
if not root:
return
stack = []
while stack or root:
if root:
stack.append(root)
root = root.left
else:
root = stack.pop()
print(root.value, end=" ")
root = root.right
def posOrderRecur(root):
# 先实现 中右左 将结果存入栈中 再依次弹出,即为后序 左右中
if not root:
return
res = []
stack = [root]
while stack:
tmp = stack.pop()
res.append(tmp.value)
if tmp.left:
stack.append(tmp.left)
if tmp.right:
stack.append(tmp.right)
while res:
print(res.pop())
【题目】 现在有一种新的二叉树节点类型如下:
public class Node { public int value; public Node left;
public Node right; public Node parent;
public Node(int data) { this.value = data; }
}
该结构比普通二叉树节点结构多了一个指向父节点的parent指针。 假
设有一 棵Node类型的节点组成的二叉树, 树中每个节点的parent指针
都正确地指向 自己的父节点, 头节点的parent指向null。 只给一个在
二叉树中的某个节点 node, 请实现返回node的后继节点的函数。 在二
叉树的中序遍历的序列中, node的下一个节点叫作node的后继节点。
# 从节点拿到跟节点 中序遍历整个树,拿到该节点的下个个节点的值即可
def get_next_Node(node):
if not node:
return
tmp = node
while tmp.parent:
tmp = tmp.parent
# tmp 即为根节点
res = []
stack = []
while stack or tmp:
if tmp:
stack.append(tmp)
tmp = tmp.left
else:
tmp = stack.pop()
res.append(tmp)
tmp = tmp.right
for i in range(len(res)-1):
if res[i] == node:
return res[i+1]
return res[-1]
如果该节点有右子节点, 那么后继是其右子节点的子树中最左端的节点
如果该节点没有右子节点, 那么后继是离它最近的祖先, 该节点在这个祖先的左子树内.
如果某个节点有右节点,则右节点的最左叶节点即为他的后继节点(左中右)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZM9Jdj4-1588470251326)(attachment:image.png)]
如果某个节点没有右节点,那么依次向上找到当前节点是左节点的父节点,这个父节点就是某个节点的后继节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EQ2hkksb-1588470251331)(attachment:image.png)]
前序遍历
中序遍历
后序遍历
按层序列化
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Codec:
def serialize(self, root: TreeNode) -> str:
"""Encodes a tree to a single string.
"""
if not root:
return "#!"
res = str(root.val) + "!"
res += self.serialize(root.left)
res += self.serialize(root.right)
return res
def deserialize(self, data: str) -> TreeNode:
"""Decodes your encoded data to tree.
"""
def reconPreorder(data):
tmp = data.pop(0)
if tmp == "#":
return None
head = TreeNode(tmp)
head.left = reconPreorder(data)
head.right = reconPreorder(data)
return head
data = data.split("!")
return reconPreorder(data)
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
【题目】 请把一段纸条竖着放在桌子上, 然后从纸条的下边向
上方对折1次, 压出折痕后展开。 此时 折痕是凹下去的, 即折痕
突起的方向指向纸条的背面。 如果从纸条的下边向上方连续对折
2 次, 压出折痕后展开, 此时有三条折痕, 从上到下依次是下折
痕、 下折痕和上折痕。
给定一 个输入参数N, 代表纸条都从下边向上方连续对折N次,
请从上到下打印所有折痕的方向。 例如: N=1时, 打印: down
N=2时, 打印: down down up
def printProcess(i,n,down):
if i > n:
return
printProcess(i+1,n,True)
print("down" if down else "up",end=" ")
printProcess(i+1,n,False)
def printAllFolds(n):
printProcess(1,n,True)
printAllFolds(4)
down down up down down up up down down down up up down up up
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YuvkmfHs-1588470251334)(attachment:image.png)]
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class ReturnData():
def __init__(self,isb,h):
self.isb = isb
self.h = h
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def process(head):
if not head:
return ReturnData(True,0)
leftData = process(head.left)
if not leftData.isb:
return ReturnData(False,0)
rightData = process(head.right)
if not rightData.isb:
return ReturnData(False,0)
if abs(leftData.h-rightData.h) > 1:
return ReturnData(False,0)
return ReturnData(True,max(leftData.h,rightData.h)+1)
return process(root).isb
搜索二叉树 中序遍历是升序
# 判断是否为搜索二叉树
def isBST(head):
if not head:
return
stack = []
res = float('-inf')
while stack or head:
if head:
stack.append(head)
head = head.left
else:
head = stack.pop()
if head.val > res :
head = head.right
else:
return False
return True
完全二叉树
(1)有右孩子,没有左孩子 False
(2)有左孩子,没有右孩子 后面遍历的结点全是叶节点
(3)左右都没有 后面遍历的结点全是叶节点
(4)左右都有 继续判断
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def isCompleteTree(self, root: TreeNode) -> bool:
if not root:
return True
queue = [root]
# 是否开启叶节点判断
flag = False
while queue:
tmp = queue.pop(0)
l = tmp.left
r = tmp.right
# 右孩子存在左孩子不存在
# flag=True 如果不是叶结点 not(not r and not l)
if r and not l or (flag and not(not r and not l)):
return False
if l:
queue.append(l)
if r:
queue.append(r)
else:
flag = True
return True
要求: 时间复杂度低于O(N), N为这棵树的节点个数
遍历左边界 得到二叉树高度 h
遍历右边界 到达最后一层,则为满二叉树
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def countNodes(self, root: TreeNode) -> int:
def bs(node,level,h):
# node 在第几层 h总高度 返回值为node为头的总节点数
if level == h:
return 1
if mostLeftLevel(node.right,level+1) == h:
# 右子树的 左高度触底,则左子树为满二叉树,递归求其右子树即可
return (1<<(h-level)) + bs(node.right,level+1,h)
else:
# 右子树的 左高度没有触底,则右子数为满二叉树(高度h-level-1)左子数递归即可
return (1<<(h-level-1)) + bs(node.left,level+1,h)
def mostLeftLevel(node,level):
while node:
level += 1
node = node.left
return level - 1
if not root:
return 0
return bs(root,1,mostLeftLevel(root,1))