python算法之二叉树

树是一种重要的数据结构,洛基在平时刷算法题遇到的一些与树有关的操作,在此记录一下。

二叉树的遍历(前、中、后序遍历的递归和非递归实现):

# 二叉树节点的定义
class TreeNode(object):
    """docstring for TreeNode"""
    def __init__(self, x):
        super(TreeNode, self).__init__()
        self.val = x
        self.left = None
        self.right = None

# 前序遍历: 根 -> 左 -> 右
def front(self, root: TreeNode) -> List[int]:
    nlist = []
    if not root:
        return nlist
    stack = []
    node = root
    while stack or node:
        while node:
            nlist.append(node.val)
            stack.append(node)
            node = node.left 
        node = stack.pop()
        node = node.right

    return nlist

# 中序遍历: 左 -> 根 -> 右
def middle(self, root: TreeNode) -> List[int]:
    nlist = []
    if not root:
        return nlist
    stack = []
    node = root
    while stack or node:
        while node:
            stack.append(node)
            node = node.left
        node = stack.pop()
        nlist.append(node.val)
        node = node.right
    return nlist

# 后序遍历: 左 -> 右 -> 根 
def last(self, root: TreeNode) -> List[int]:
    nlist = []
    if not root:
        return nlist
    stack = []
    node = root
    while stack or node:
        while node:
            stack.append(node)
            if node.left:
                node = node.left
            else:
                node = node.right
        node = stack.pop()
        nlist.append(node.val)
        # 这个时候我们需要看,当前被访问的节点是左孩子还是右孩子,如果是左孩子,那么我们需要再访问一下右孩子;
		# 如果是右孩子,我们直接访问父亲节点即可。
        if stack and stack[-1].left == node:
            node = stack[-1].right
        else:
        	# node=None之后,程序会直接访问父节点;不能用node=stack.pop(),否则程序会再重新往下查找孩子节点!
            node = None 
    return nlist

# 二叉树的层次遍历
def hierarchy(self, root: TreeNode) -> List[int]:
    nlist = []
    if not root:
        return nlist
    cur = [root]
    while cur:
        nextLayer = []
        for node in cur:
            if node:
                nlist.append(node.val)
                if node.left:
                    nextLayer.append(node.left)
                if node.right:
                    nextLayer.append(node.right)
        cur = nextLayer
    return nlist


# 递归的方法前序遍历
def front_recursive(self, node):
    if not node:
        return
    print(node.val)
    front_travel(node.left)
    front_travel(node.right)

# 递归的中序、后序遍历与前序遍历相似
def middle_recursive(self, node):
	if not node:
		return
	middle_recursive(node.left)
	print(node.val)
	middle_recursive(node.right)

def right_recursive(self, node):
	if not node:
		return
	right_recursive(node.left)
	right_recursive(node.right)
	print(node.val)

递归的方式判断两棵树是否相同:

# Definition for a binary tree node
class TreeNode:
	def __init__(self, x):
		self.val = x
		self.left = None
		self.right = None

class Solution:
	def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
		if p and not q:
			return False
		if q and not p:
			return False
		if not p and not q:
			return True
		return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

 判断一棵二叉树是否是对称二叉树:

# Definition for a binary tree node
class TreeNode:
	def __init__(self, x):
		self.val = x
		self.left = None
		self.right = None

class Solution:
	# 思路一,用递归的方法,和判断相同的树,思路差不多,
	#        只是递归的时候用节点1的左子树与节点2的右子树做对比了。
	def isSymmetric(self, root: TreeNode) -> bool:

		def check(node_1, node_2) -> bool:
			if not node_1 and node_2:
				return False
			if node_1 and not node_2:
				return False
			if not node_1 and not node_2:
				return True
			return node_1.val = node_2.val and check(node_1.left, node_2.right) and check(node_1.right, node_2.left)
	    
	    return check(root.left, root.right)

    # 思路二:用栈来存储这棵树里处在对称位置的节点。
    #        用p,q表示一对处在对称位置的节点(初始为根节点的左、右孩子),比较他们的值;
    #        接着将p的左孩子与q的右孩子入栈,将p的右孩子与q的左孩子入栈。
    #        然后从栈里pop一对节点出来,这一对节点将是对称位置的节点,继续比较。
	def isSymmetric_2(self, root: TreeNode) -> bool:
		if not root: # 询问面试官,如果根节点不存在怎么办
			return True
		if not root.left and not root.right:
			return True
		stack = [root.left, root.right]
		while stack:
			r = stack.pop()
			l = stack.pop()
			# 都不为空
			if l and r:
				if l.val != r.val:
					return False
				stack.extend([l.left, r.right, l,right, r.left])
			# 全为空
			elif not l and not r:
				continue
			# 剩下的就是 l 和 r 中有一个是None的情况
			else:
				return False
		return True

判断一棵树是否是平衡二叉树:

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

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        curLevel = [root]
        level = 0
        while curLevel:
            nextLevel = []
            for node in curLevel:
                if node.left:
                    nextLevel.append(node.left)
                if node.right:
                    nextLevel.append(node.right)
            curLevel = nextLevel
            level = level + 1
        return level

    def is_balanced(self, root: TreeNode) -> bool:
        if not root:
            return True
        return abs(maxDepth(root.left) - maxDepth(root.right)) <= 1 \
        and is_balanced(root.left) and is_balanced(root.right)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值