二叉树练习

中序遍历

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


def in_order_traversal(root):  # 中序
    res = []
    stack = []#借用栈
    if root is None:
        return res
    cur = root
    while len(stack) != 0 or cur is not None:
        while cur is not None:
            stack.append(cur)
            cur = cur.left
        node = stack.pop()
        res.append(node.val)
        cur = node.right
    return res
    
# 中序打印二叉树(递归)
def inOrderTraverse(node):
    if node is None:
        return None
    inOrderTraverse(node.left)
    print(node.val)
    inOrderTraverse(node.right)

前序遍历

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


def pre_order_traversal(root):  # 前序
    result = []
    stack = []
    stack.append(root)
    while len(stack) != 0:
        node = stack.pop()
        if node is None:
            continue
        result.append(node.val)
        stack.append(node.right)
        stack.append(node.left)
    return result
    
# 先序打印二叉树(递归)
def preOrderTraverse(node):
    if node is None:
        return None
    print(node.val)
    preOrderTraverse(node.left)
    preOrderTraverse(node.right)

后序遍历

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


def post_order_traversal(root):  # 后序
    """
    前序遍历为 root -> left -> right,后序遍历为 left -> right -> root,
    可以修改前序遍历成为 root -> right -> left,那么这个顺序就和后序遍历正好相反
    """
    result = []
    stack = []
    stack.append(root)
    while len(stack) != 0:
        node = stack.pop()
        if node is None:
            continue
        result.append(node.val)
        stack.append(node.left)
        stack.append(node.right)
    return result[::-1]
    
# 后序打印二叉树(递归)
def postOrderTraverse(node):
    if node is None:
        return None
    postOrderTraverse(node.left)
    postOrderTraverse(node.right)
    print(node.val)

从上往下打印二叉树(简单)

题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

思路:

  1. 根节点不存在 返回空

  2. 开辟queue空间 初始化为[root] 队列意味着一层一层的遍历

  3. 开辟放结果的数组 res

  4. 当队列不为空时while:
    计算这一层有几个节点n
    遍历这一层for
    如果这一层不存在节点 退出for循环
    否则 取出一个节点 添加到放结果的数组res
    将下一层的节点都添加到队列 即如果该节点左右节点存在添加到队列

  5. 返回res

运行时间:26ms

占用内存:5860k

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
def construct_tree():
    root = TreeNode(8)
    root.left = TreeNode(6)
    root.right = TreeNode(10)
    root.left.left = TreeNode(5)
    root.left.right = TreeNode(7)
    root.right.left = TreeNode(9)
    root.right.right = TreeNode(11)
    root.left.right.left = TreeNode(12)
    root.left.right.right = TreeNode(13)
    return root
class Solution:
    # 返回从上到下每个节点值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        # write code here
        if not root:return []
        queue=[root]
        res=[]
        while queue:
            n=len(queue)
            for _ in range(n):
                if not queue:break
                temp=queue.pop(0)
                res.append(temp.val)
                if temp.left:
                    queue.append(temp.left)
                if temp.right:
                    queue.append(temp.right)
        return res
s=Solution()
tree= construct_tree()
res=s.PrintFromTopToBottom(tree)
print(res)  
#return [8, 6, 10, 5, 7, 9, 11, 12, 13]

按之字形打印二叉树

题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

思路:
同上一道题,不同之处在于添加了标记偶数行的标记 j,j 初始化为-1 ,每开始新一行的循环 j 就加一,最后每一行遍历完后 判断这是奇数行还是偶数行,偶数行的话,反转这一行的数值。第二个不同之处在于,开辟了放每一行数值的暂存数组temp,因为偶数行的话,必须反转后才能添加到结果数组res里面。

运行时间:27ms

占用内存:5728k

class Solution:
    def Print(self, pRoot):
        # write code here
        if not pRoot: return []
        res = []#放结果的数组
        queue = [pRoot]
        j = -1#标记偶数行
        while queue:
            j += 1
            n = len(queue)
            temp = []#放这一行的节点数值
            for _ in range(n):
                node = queue.pop(0)
                temp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            if j % 2:#当j表示这一行为偶数行 反转这一行
                temp.reverse()
            res.append(temp)#把这一行确定的节点数值放进结果数组里
        return res
        
s=Solution()
tree= construct_tree()
res=s.Print(tree)
print(res) 

把二叉树打印成多行

题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

运行时间:25ms

占用内存:5632k

class Solution:
    # 返回二维列表[[1,2],[4,5]]
    def Print(self, pRoot):
        # write code here
        if not pRoot: return []
        queue = [pRoot]
        res = []
        while queue:
            n = len(queue)
            temp = []
            for _ in range(n):
                node = queue.pop(0)
                temp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            res.append(temp)
         #   print(res)
        return res
#return [[8], [6, 10], [5, 7, 9, 11]]

对称的二叉树

题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

思路:

如果根节点不存在 返回真
把每一层放进队列 queue = [pRoot]

当队列里有节点时 进行以下操作
看这一层有多少个节点 n

如果非根节点且这一层节点数是奇数
则返回false
否则
重点,判断这一行最左和最右是否一样

【判断两个节点一样么
两节点都不存在则两节点一样
两节点都存在且数值一样则两节点一样
否则返回不一样】

遍历这一行
弹出队列中的一个节点
如果该节点不存在 过
否则将下一层的节点都添加到队列 即如果该节点左右节点存在添加到队列

运行时间:25ms

占用内存:5732k

class Solution:
    def isEqual(self,p1, p2):
        if not p1 and not p2:
            return True
        elif p1 and p2 and p1.val == p2.val:
            return True
        else:
            return False
    def isSymmetrical(self, pRoot):
        # write code here
        if not pRoot: return True
        queue = [pRoot]
        while queue:
#            print(queue)
            n = len(queue)
            if queue[0] != pRoot and n % 2 != 0: 
                return False
            for i in range(n//2):
                if not self.isEqual(queue[i], queue[-1-i]):
                    return False
            for _ in range(n):
                node = queue.pop(0)
                if not node: continue
                queue.append(node.left)
                queue.append(node.right)
        return True

二叉树的下一个结点

题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

思路:
分情况讨论

  1. 第一:节点p的右节点存在:p的下一个节点 则为p的右子树的最左节点 [1.1】
  2. 第二:节点p的右节点不存在的话 分两种情况:
    第一 :节点p的右节点不存在的话 且 p为其父节点的左子节点:p的下一个节点 则为p的父节点 【2.1】
    第二:节点p的右节点不存在的话 且 p为其父节点的右子节点: p的下一个节点 为 沿着父节点往上遍历 找到一个点 满足该点是其父节点的左子节点。(若该点不存在,则p的下一个节点不存在)【2.2】

如果该节点为空 返回None
p的右节点存在的话
找到右子树的最左节点 返回

节点p的右节点不存在的话 且 p为其父节点的右子节点 时:
关键,往上遍历 当pNode是自己父节点的左子节点时,跳出while
返回pNode的父节点

运行时间:26ms

占用内存:5864k

def construct_tree():
    root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(5)
    root.right.left = TreeNode(6)
    root.right.right = TreeNode(7)
    root.left.right.left = TreeNode(8)
    root.left.right.right = TreeNode(9)
     '''
    root = TreeNode('a')
    root.left = TreeNode('b')
    root.right = TreeNode('c')
    root.left.left = TreeNode('d')
    root.left.right = TreeNode('e')
    root.right.left = TreeNode('f')
    root.right.right = TreeNode('g)
    root.left.right.left = TreeNode('h')
    root.left.right.right = TreeNode('i')
    '''
    root.parent = None
    root.left.parent= root
    root.right.parent= root
    root.left.left.parent= root.left
    root.left.right.parent =root.left
    root.right.left.parent= root.right
    root.right.right.parent= root.right
    root.left.right.left.parent = root.left.right
    root.left.right.right.parent =root.left.right
    return root

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

class Solution:
    def GetNext(self, pNode):
        # write code here
        if not pNode: return None
        if pNode.right:  # 
            p = pNode.right
            while p.left:
                p = p.left
            return p
         # 
        while pNode.parent and pNode.parent.right == pNode:
            pNode = pNode.parent
        return pNode.parent
        
        
root=construct_tree()
s=Solution()
#res=s.GetNext(root.left.left)
res=s.GetNext(root.right.left)
print(res.val)

二叉树的深度

题目描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

思路:
队列queue 用来放每一层节点

运行时间:28ms

占用内存:5728k

class Solution:
    def TreeDepth(self, pRoot):
        # write code here
        if not pRoot: return 0#根节点不存在 返回0
        queue = [pRoot]# 把每一层放进队列
        deep = 0#深度初始化为0
        while queue:#当这一层有节点时
            n = len(queue)#看着一层有几个节点n
            for _ in range(n):#遍历这一层的n个节点
                node = queue.pop(0)#弹出一个,并把弹出的节点的下一层的节点(即左右子节点)添加到队列
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            deep += 1#每一层遍历完 深度加一
        return deep

二叉搜索树的第k个结点

题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

运行时间:26ms

占用内存:5864k

树的子结构

题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

重建二叉树(中等)

题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

思路

用前序遍历找到根结点,用根结点在中序遍历中切开左右子树,递归重建二叉树

  1. 前序数组为空时,返回空
  2. 用前序遍历找到根结点
  3. 初始化一个为根值的树节点
  4. 遍历后序数组,找到根数值的索引位置i
  5. 切分左右子树,递归调用本函数
  6. 返回根节点

运行时间:42ms

占用内存:5724k

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if not pre:
            return
        root_val=pre[0]
        root=TreeNode(root_val)
        for i in range(len(tin)):
            if tin[i]==root_val:break
        root.left=self.reConstructBinaryTree(pre[1:1+i],tin[:i])
        root.right=self.reConstructBinaryTree(pre[1+i:],tin[i+1:])
        return root

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

你可能感兴趣的:(LeetCode)