PYDSA-OJ-9-BinTree_1

PYDSA-OJ-9-BinTree_1

二叉树复原(10分)

  1. 题目内容:

    给定一种序列化二叉树的方式:从根节点起始按层次遍历二叉树所有“可能”存在节点的位置:若该位置存在节点,则输出节点值,并在下一层相应增加两个可用位置;否则输出None,且不增加下一层的可用位置。

    例如"[5, 4, 7, 3, None, 2, None, -1, None, 9]"是下图所示的二叉树序列化的结果:

其中红色箭头对所有的None进行了标记。

现给出一个二叉树以这种形式序列化的结果,请复原该二叉树并给出它的中序遍历。
  1. 输入格式:

    一行合法的Python表达式,可解析为包含整数与None的列表

  2. 输出格式:

    二叉树中序遍历的整数序列,以空格分隔

  3. 输入样例:

    [5, 4, 7, 3, None, 2, None, -1, None, 9]

  4. 输出样例:

    -1 3 4 5 9 2 7

  5. 输入样例2:

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

  6. 输出样例2:

    1 5 3 4 6

    注:树结构如图(红色箭头对None的对应位置进行了标记)

  1. 参考代码模板

def seq2tree(seq):
    # 将列表反序列化为树
    pass
 
def inorderTree(root):
    # 中序遍历树
    pass
 
lst = eval(input())
tree = seq2tree(lst)
inorder = inorderTree(tree)
print(inorder) # 请自行确定打印方式

解答一

解答思路:列表补全二叉树,然后直接遍历

# 能用的方案,但是OJ的最后一个用例通不过,原因不详
def inorder(lst, root, outcome):
    '''中序遍历'''
    if root*2 <= len(lst):
        inorder(lst, root*2, outcome)
    if lst[root-1]:
        outcome.append(lst[root-1])
    if root*2+1 <= len(lst):
        inorder(lst, root*2+1, outcome)

def complete_tree(lst):
    '''补全二叉树成完全二叉树'''
    for i in range(len(lst)):
        if lst[i] == None and 2*i+1<len(lst):
            lst.insert(2*i+1, None)
            lst.insert(2*i+2, None)
    return lst
    
def main():
    outcome = []
    inorder(complete_tree(eval(input())), 1, outcome)
    print(*outcome)

main()

解答二

构造二叉树类,用链表实现,忘了写注释,自己都看不懂了

# 方案一
class BinaryTree:
    def __init__(self, data=None):
        self.data = data
        self.left = None
        self.right = None

    def buildTree(self, alist):
        root = BinaryTree(alist.pop(0))
        temp_deque = []
        temp_deque.append(root)
        while True:
            try:
                temp_tree = temp_deque.pop(0)
                if temp_tree.data:
                    temp_tree.left = BinaryTree(alist.pop(0))
                    temp_tree.right = BinaryTree(alist.pop(0))
                    temp_deque.append(temp_tree.left)
                    temp_deque.append(temp_tree.right)
            except IndexError:
                break
        self.data = root.data
        self.left = root.left
        self.right = root.right
        
    def print_inorder(self, outcome):
        if self.left:
            self.left.print_inorder(outcome)
        if self.data:
            outcome.append(self.data)
        if self.right:
            self.right.print_inorder(outcome)
        return outcome
    
def main():
    alist = eval(input())
    temp = BinaryTree(0)
    temp.buildTree(alist)
    print(*temp.print_inorder([]))
    
main()

翻转二叉树(10分)

  1. 题目内容:

给定一个二叉树,请给出它的镜面翻转。

为方便起见,本题只给出完全二叉树的层次遍历,请给出相应的翻转二叉树的中序遍历。

备注:

这个问题来自开源软件开发者Max Howell在Google面试被拒的经历 :

谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了

  1. 输入格式:

一行空格分隔的整数序列,表示一个完全二叉树的层次遍历

  1. 输出格式:

一行空格分隔的整数序列,表示翻转后的二叉树的中序遍历

  1. 输入样例:

4 2 7 1 3 6 9

  1. 输出样例:

9 7 6 4 3 2 1

解答一

解题思路:对称后遍历顺序改变即可

def inorder(lst, root, outcome):
    if 2*root+1 <= len(lst):
        inorder(lst, 2*root+1, outcome)
    outcome.append(lst[root-1])
    if 2*root <= len(lst):
        inorder(lst, 2*root, outcome)
        
def main():
    outcome = []
    inorder(input().split(), 1, outcome)
    print(*outcome)
    
main()

解答二

解题思路:我是个智障,别管我,leave me alone

import math


class BinaryTree:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
    
    def buildTree2(self, alist):
        root = BinaryTree(alist.pop(0))
        from collections import deque
        temp_deque = deque()
        temp_deque.append(root)
        while True:
            temp_tree = temp_deque.popleft()
            try:
                temp_tree.left = BinaryTree(alist.pop(0))
                temp_tree.right = BinaryTree(alist.pop(0))
                temp_deque.append(temp_tree.left)
                temp_deque.append(temp_tree.right)
            except IndexError:
                break
        self.data = root.data
        self.left = root.left
        self.right = root.right
        
    def buildTree(self, alist):
        root = BinaryTree(alist.pop(0))
        
        temp_deque = []
        temp_deque.append(root)
        while True:
            temp_tree = temp_deque.pop(0)
            try:
                temp_tree.left = BinaryTree(alist.pop(0))
                temp_tree.right = BinaryTree(alist.pop(0))
                temp_deque.append(temp_tree.left)
                temp_deque.append(temp_tree.right)
            except IndexError:
                break
        self.data = root.data
        self.left = root.left
        self.right = root.right
        
    def print_inorder(self, temp):
        
        if self.left:
            self.left.print_inorder(temp)
        if self.data:
            temp.append(self.data)
        if self.right:
            self.right.print_inorder(temp)
        return temp
        
def lst_sym(string):
    lst_in = string.split()
    num_lev = int(math.log(len(lst_in)+1 ,2))
    for i in range(1, num_lev):
        temp = lst_in[2**i-1:2**(i+1)-1]
        temp.reverse()
        lst_in = lst_in[:2**i-1] + temp + lst_in[2**(i+1)-1:]
    return lst_in

def main():
    outcome = []
    temp = lst_sym(input())
    temp_tree = BinaryTree(0)
    temp_tree.buildTree(temp)
    print(*temp_tree.print_inorder(outcome))
    
main()

多叉树遍历(10分)

  1. 题目内容:

给定以嵌套列表形式给出的多叉树,求它的后序遍历

注:每个代表非空多叉树的列表包含至少一项;列表第一项代表节点值,其后每一项分别为子树;遍历子树时以列表下标从小到大的顺序进行。

  1. 输入格式:

一行合法的Python表达式,可解析为嵌套列表形式的多叉树结构

  1. 输出格式:

一行整数,以空格分隔

  1. 输入样例:

[1,[2,[3,[4],[5]],[6]],[7],[8,[9],[10]]]

  1. 输出样例:

4 5 3 6 2 7 9 10 8 1

解答

解题思路:就递归一下喽,前面看得懂,这个也不会不懂

alist = eval(input())

def decode_tree(alist, outcome):
    temp = alist.pop(0)
    for each in alist:
        decode_tree(each, outcome)
    outcome.append(temp)
    
outcome = []

decode_tree(alist, outcome)
print(*outcome)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值