Java记录 -65- 遍历map方法

本文介绍了Java中HashMap的三种遍历方法:通过调用toString()方法显示所有键值对;通过keySet()获取键,再获取对应的值;通过entrySet()获取包含键和值的Entry对象。

Map接口提供了多个遍历元素的方法:

public class HashMapTest {    public static void main(String[] args){        HashMap map = new HashMap();        map.put("a", "aaa");        map.put("f", "fff");        map.put("s", "sss");                //1.直接利用map的toString()方法,返回map中的所有键值对信息        System.out.println(map); //{f=fff, s=sss, a=aaa}                //2.先获取到map的key,然后利用key再获取到value        for(Object key : map.keySet()){            Object value = map.get(key);            System.out.println(key+"="+value);        }                //3.直接从map中获取到包含key和value的entry对象,再用每个entry对象来获得其中的key和value        for(Object obj: map.entrySet()){            Map.Entry entry = (Map.Entry)obj;            System.out.println(entry.getKey()+"="+entry.getValue());        }    }}


<think>好的,我现在需要解决用户关于L2-006树的遍历问题的Java实现的问题。首先,用户提到了三个引用,其中引用[1]和[2]描述了题目要求,即根据后序和中序遍历重建二叉树并输出层序遍历结果。引用[3]提供了一个输入输出样例,以及可能的Java实现线索。 首先,我要明确题目的要求。题目给出二叉树的后序和中序遍历序列,要求输出层序遍历的结果。键值都是互不相同的正整数,节点数N不超过30。输入格式是三个行,第一行是N,第二行是后序序列,第三行是中序序列。 接下来,我需要回忆如何根据后序和中序序列重建二叉树。后序遍历的最后一个元素是根节点,然后在中序遍历中找到该根节点,左边是左子树,右边是右子树。根据左子树和右子树的节点数量,可以在后序遍历中划分左右子树的后序序列。递归这个过程即可构建整个二叉树。 然后,层序遍历需要用到队列,按层次输出节点值。这在Java中可以用LinkedList作为队列来实现。 现在,考虑Java实现的具体步骤。首先,读取输入,获取后序和中序数组。然后,递归构建二叉树。每个递归函数需要当前子树的后序序列起始和结束位置,以及中序序列的起始和结束位置。每次确定根节点,分割左右子树,递归处理左右子树。 需要注意数组索引的处理,容易出错。例如,后序数组中根的位置在最后,左子树的范围是从当前后序的起始位置开始,长度为左子树的节点数(由中序中根的位置确定)。右子树的范围则是左子树之后到根之前的位置。 接下来,处理具体的递归函数。例如,给定后序数组的postStart和postEnd,中序数组的inStart和inEnd。找到根在中序中的位置index,左子树的节点数为index - inStart。因此,在后序数组中,左子树的后序范围是postStart到postStart + leftSize -1,右子树则是postStart + leftSize到postEnd -1。 构建完二叉树后,进行层序遍历。使用队列,首先将根节点入队,然后循环出队,访问节点,并将左右子节点入队,直到队列为空。 现在,考虑代码的结构。首先定义TreeNode类,包含val、left、right。然后读取输入,处理成后序和中序数组。编写递归构建函数buildTree,参数包括后序数组、当前后序的起始结束位置,中序数组的起始结束位置,以及中序的哈希映射(用于快速查找根的位置)。使用哈希表存储中序的值到索引的映射,可以加速查找过程。 在Java中,主函数需要处理输入,比如使用Scanner读取输入行,分割成整数数组。例如,读取第二行为后序数组,第三行为中序数组。然后调用buildTree函数构建二叉树,接着层序遍历输出结果。 可能的错误点包括数组索引的计算是否正确,递归终止条件是否正确(比如当postStart > postEnd时返回null)。另外,处理输入时需要注意数组的长度是否正确,避免越界。 测试样例中的输入是7个节点,后序是2 3 1 5 7 6 4,中序是1 2 3 4 5 6 7。构建后的根应该是4,左子树的中序是1 2 3,后序是2 3 1;右子树的中序是5 6 7,后序是5 7 6。层序遍历输出应为4 1 6 3 5 7 2,与样例一致。 现在,编写代码的大致步骤: 1. 定义TreeNode类。 2. 读取输入,获取后序和中序数组。 3. 创建中序值到索引的哈希表。 4. 递归构建二叉树。 5. 层序遍历二叉树,收集结果。 6. 输出结果,空格分隔。 在递归构建函数中,每次确定根的值,分割左右子树的后序和中序范围。例如,根的值是post[postEnd],在中序中找到位置index。左子树节点数为index - inStart。因此,后序中左子树的范围是postStart到postStart + leftSize -1,右子树是postStart + leftSize到postEnd -1。 对于层序遍历,使用队列,每次取出节点,记录其值,然后加入左右子节点。 现在,考虑代码的具体实现。例如: 读取输入部分: Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.nextLine(); // 读取换行符 int[] postOrder = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray(); int[] inOrder = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray(); 然后,创建哈希表: Map<Integer, Integer> inMap = new HashMap<>(); for (int i = 0; i < n; i++) { inMap.put(inOrder[i], i); } 构建树的函数: private TreeNode buildTree(int[] post, int postStart, int postEnd, int[] in, int inStart, int inEnd, Map<Integer, Integer> inMap) { if (postStart > postEnd || inStart > inEnd) return null; int rootVal = post[postEnd]; TreeNode root = new TreeNode(rootVal); int inRoot = inMap.get(rootVal); int leftSize = inRoot - inStart; root.left = buildTree(post, postStart, postStart + leftSize -1, in, inStart, inRoot -1, inMap); root.right = buildTree(post, postStart + leftSize, postEnd -1, in, inRoot +1, inEnd, inMap); return root; } 然后调用: TreeNode root = buildTree(postOrder, 0, n-1, inOrder, 0, n-1, inMap); 层序遍历部分: List<Integer> result = new ArrayList<>(); Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); result.add(node.val); if (node.left != null) queue.offer(node.left); if (node.right != null) queue.offer(node.right); } 最后输出结果: System.out.println(result.stream().map(String::valueOf).collect(Collectors.joining(" "))); 可能需要注意的细节是,当n为0时的情况处理,但题目中N>=1?根据题目描述,N是正整数,所以可能不需要处理n=0的情况。 测试样例是否正确?例如输入为7,后序2 3 1 5 7 6 4,中序1 2 3 4 5 6 7,构建的树根是4,左子树的根是1(后序的第三个元素?需要再仔细看构建过程是否正确)。 可能存在的错误是分割后序数组时的范围是否正确。例如左子树的节点数是inRoot - inStart,在后序数组中,左子树的后序范围应为postStart到postStart + leftSize -1,右子树则是postStart + leftSize到postEnd -1。 例如,样例中的后序最后一个是4,即根。在中序中4的位置是3,左子树有三个节点(1,2,3),所以左子树的后序范围是前三个元素(2,3,1),右子树的后序是接下来的三个元素(5,7,6)。然后递归处理左右子树。 这样构建的树结构应该正确,层序遍历结果如样例所示。 综上所述,Java实现的关键点在于正确分割后序和中序数组,递归构建二叉树,然后进行层序遍历。需要仔细处理数组的索引,避免越界和错误分割。</think>### L2-006 树的遍历 Java 实现 #### 解题思路 题目要求根据二叉树的**后序遍历**和**中序遍历**序列,输出其**层序遍历**结果。实现步骤如下: 1. **重建二叉树**:利用后序遍历确定根节点,结合中序遍历划分左右子树,递归构建二叉树[^1]。 2. **层序遍历**:使用队列按层次遍历二叉树,逐层输出节点值。 --- #### Java 代码实现 ```java import java.util.*; class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.nextLine(); // 处理换行符 // 读取后序和中序序列 int[] postOrder = Arrays.stream(scanner.nextLine().split(" ")) .mapToInt(Integer::parseInt).toArray(); int[] inOrder = Arrays.stream(scanner.nextLine().split(" ")) .mapToInt(Integer::parseInt).toArray(); // 构建中序哈希映射,加速查找根节点位置 Map<Integer, Integer> inMap = new HashMap<>(); for (int i = 0; i < n; i++) { inMap.put(inOrder[i], i); } // 递归构建二叉树 TreeNode root = buildTree(postOrder, 0, n-1, inOrder, 0, n-1, inMap); // 层序遍历并输出结果 List<Integer> levelOrder = levelTraversal(root); System.out.println( levelOrder.stream() .map(String::valueOf) .collect(Collectors.joining(" ")) ); } // 递归构建二叉树 private static TreeNode buildTree(int[] post, int postStart, int postEnd, int[] in, int inStart, int inEnd, Map<Integer, Integer> inMap) { if (postStart > postEnd || inStart > inEnd) return null; // 根节点为后序序列的最后一个元素 int rootVal = post[postEnd]; TreeNode root = new TreeNode(rootVal); // 根节点在中序序列中的位置 int inRootIdx = inMap.get(rootVal); int leftSubtreeSize = inRootIdx - inStart; // 左子树节点数 // 递归构建左子树和右子树 root.left = buildTree(post, postStart, postStart + leftSubtreeSize - 1, in, inStart, inRootIdx - 1, inMap); root.right = buildTree(post, postStart + leftSubtreeSize, postEnd - 1, in, inRootIdx + 1, inEnd, inMap); return root; } // 层序遍历 private static List<Integer> levelTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); Queue<TreeNode> queue = new LinkedList<>(); if (root != null) queue.offer(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); result.add(node.val); if (node.left != null) queue.offer(node.left); if (node.right != null) queue.offer(node.right); } return result; } } ``` --- #### 代码说明 1. **输入处理** - 使用 `Scanner` 读取输入,转换为后序和中序数组。 2. **哈希表优化** - 将中序序列的值与索引存入哈希表,快速定位根节点位置[^2]。 3. **递归构建树** - 后序序列的最后一个元素是当前子树的根节点。 - 根据中序序列中根的位置划分左右子树,递归构建。 4. **层序遍历** - 使用队列按层次遍历,依次输出节点值。 --- #### 示例测试 **输入** ``` 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 ``` **输出** ``` 4 1 6 3 5 7 2 ``` 与题目要求一致[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值