ACM模式下的二叉树的输入

文章讲述了如何在ACM竞赛中处理完全二叉树和非完全二叉树的输入格式,包括完全二叉树的层序遍历表示、使用数组和链表构建二叉树,并演示了中序遍历的应用。

二叉树的输入

1.完全二叉树格式输入

acm模式中一般用输入一行数字代表一个二叉树,一般会以完全二叉树格式输入。这行数字的按照层序遍历的顺序排列,且其中空节点一般会用特定的符号表示,如0或是null可以直接用数组表示二叉树,例如列表Tree, 将Tree[i]的左子树和右子树分别为Tree[2i+1]和Tree[2i+2],不过会比较占用空间。

# 中序遍历
def inorder_traversal(nums, index):
    if index >= len(nums) or nums[index] == -1:
        return
    left, right = 2 * index + 1, 2 * index + 2
    inorder_traversal(nums, left)
    print(nums[index], end = ' ')
    inorder_traversal(nums, right)
	  
	  
# 输入为 1 2 3 null 4 null 5
#      1
#    /   \
#   2     3
#    \     \
#     4     5
if __name__ == "__main__":
    nums = input().split()
    nums = [int(num) if num != 'null' else -1 for num in nums]
    inorder_traversal(nums, 0)

    # output: 2 4 1 3 5 

也可以用链表实现,更省空间,但操作更复杂一些。

# 定义二叉树类函数
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
	  
	  
# 由数组转二叉树
def construct_binary_tree(nums, index):
    if index >= len(nums):
        return
    # -1作为空节点
    if nums[index] == -1:
        return None
    left = index * 2 + 1
    right = index * 2 + 2
    root = TreeNode(nums[index])
    root.left = construct_binary_tree(nums, left)
    root.right = construct_binary_tree(nums, right)
    return root

# 中序遍历
def inorder_traversal(root):
    if not root: 
    	return
    inorder_traversal(root.left)
    print(root.val, end=' ')
    inorder_traversal(root.right)

# 输入为 1 2 3 null 4 null 5
#      1
#    /   \
#   2     3
#    \     \
#     4     5
if __name__ == "__main__":
	nums = input().split()
	nums = [int(num) if num != 'null' else -1 for num in nums]
	root = construct_binary_tree(nums, 0)
	inorder_traversal(root)
   # output: 2 4 1 3 5
	  

2.其他格式输入(是不是完全二叉树都可以)(可以统一用这个)

有部分题目的输入格式不是完全二叉树,例如leetcode的二叉树格式,输入的数组虽然也是按照层序遍历的顺序,但并不是每一层的空节点都会表示出来,而是仅表示与非空节点连接的空节点。

# 定义二叉树类函数
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


import collections


# 数组转二叉树
def construct_binary_tree(nums):  # ['1', 'null', '1', 'null', '1', '2']
    if nums == []:
        return
    root = TreeNode(nums[0])
    queue = collections.deque()
    queue.append(root)
    i = 1
    while i < len(nums):
        node = queue.popleft()
        if i < len(nums) and nums[i] != -1:
            node.left = TreeNode(nums[i])
            queue.append(node.left)
        i += 1
        if i < len(nums) and nums[i] != -1:
            node.right = TreeNode(nums[i])
            queue.append(node.right)
        i += 1
    return root


# 中序遍历
def inorder_traversal(root):
    if not root: 
    	return
    inorder_traversal(root.left)
    print(root.val, end=' ')
    inorder_traversal(root.right)


# 输入 1 null 1 null 1 2
#    1
#  /  \
# null  1
#    /   \
#   null  1
#        /
#       2
if __name__ == "__main__":
    nums = ['1', 'null', '1', 'null', '1', '2']
    nums = [int(num) if num != 'null' else -1 for num in nums]
    root = construct_binary_tree(nums)
    inorder_traversal(root)
# 输出 1 1 2 1

3.构建完全二叉树输入用例(输出带有null)

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


# 根据数组构建二叉树

def construct_binary_tree(nums: []) -> TreeNode:
    if not nums:
        return None
    # 用于存放构建好的节点
    root = TreeNode(-1)
    Tree = []
    # 将数组元素全部转化为树节点
    for i in range(len(nums)):
        if nums[i] != -1:
            node = TreeNode(nums[i])
        else:
            node = None
        Tree.append(node)
        if i == 0:
            root = node
    # 直接判断2*i+2<len(Tree)会漏掉2*i+1=len(Tree)-1的情况
    for i in range(len(Tree)):
        if Tree[i] and 2 * i + 1 < len(Tree):
            Tree[i].left = Tree[2 * i + 1]
            if 2 * i + 2 < len(Tree):
                Tree[i].right = Tree[2 * i + 2]
    return root


# 算法:中序遍历二叉树

class Solution:
    def __init__(self):
        self.T = []

    def inorder(self, root: TreeNode) -> []:
        if not root:
            return
        self.inorder(root.left)
        self.T.append(root.val)
        self.inorder(root.right)
        return self.T


# 验证创建二叉树的有效性,二叉排序树的中序遍历应为顺序排列
# 输入 1 null 1 null 1 2
#    1
#  /  \
# null  1
#     /   \
#   null  1
#        /
#       2

test_tree = ['1', 'null', '1', 'null', '1', '2']
root = construct_binary_tree(test_tree)
A = Solution()
print(A.inorder(root))
# 输出:['null', 'null', '1', '1', '2', '1']
### Java 实现 ACM 竞赛中的二叉树和图的输入ACM 竞赛中,处理数据结构如二叉树和图是非常常见的任务。以下是关于如何通过 Java 来实现这些数据结构的输入方法。 #### 一、二叉树输入实现 对于二叉树输入,通常会采用层次遍历的方式读取节点及其子节点的关系。下面是一个基于数组表示法的二叉树构建方式: ```java import java.util.*; public class BinaryTree { static class TreeNode { int val; TreeNode left, right; public TreeNode(int item) { this.val = item; this.left = null; this.right = null; } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); String[] nodes = sc.nextLine().split(" "); // 输入层序序列 List<TreeNode> list = new ArrayList<>(); for (int i = 0; i < nodes.length; i++) { if (!nodes[i].equals("#")) { // "#" 表示空节点 list.add(new TreeNode(Integer.parseInt(nodes[i]))); } else { list.add(null); // 添加null代表无节点 } } for (int i = 0; i < list.size() / 2 && !list.get(i).equals(null); i++) { if ((i * 2 + 1) < list.size()) { list.get(i).left = list.get(2 * i + 1); } if ((i * 2 + 2) < list.size()) { list.get(i).right = list.get(2 * i + 2); } } System.out.println("Binary Tree Built Successfully!"); } } ``` 上述代码实现了从标准输入读取一个字符串形式的层序序列来创建一棵二叉树[^3]。 #### 二、图的输入实现 图可以由邻接矩阵或者邻接表两种方式进行存储,在竞赛环境中更常用的是邻接表的形式。下面是使用邻接表构建有向加权图的一个例子: ```java import java.util.*; public class Graph { static class Edge { int src, dest, weight; public Edge(int s, int d, int w) { this.src = s; this.dest = d; this.weight = w; } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int V = sc.nextInt(); // 节点数 int E = sc.nextInt(); // 边数 List<List<Edge>> adjListArray = new ArrayList<>(V); for (int i = 0; i < V; i++) { adjListArray.add(new ArrayList<>()); } while(E-- > 0){ int u = sc.nextInt(); int v = sc.nextInt(); int wt = sc.nextInt(); adjListArray.get(u).add(new Edge(u,v,wt)); // 构建边关系 } System.out.println("Graph Built Successfully!"); } } ``` 此代码片段展示了如何利用 `Scanner` 类从控制台接收顶点数量、边的数量以及每条边的具体信息,并将其转化为邻接列表表示的图结构[^4]。 #### 动态窗口避障算法简介 虽然本问题是针对二叉树与图的数据结构输入讨论,但提到动态窗口避障算法(Dynamic Window Approach),它是一种实时局部路径规划技术,主要用于移动机器人领域解决碰撞规避问题[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值