无法理解BST转Max Heap时的树结构变化及代码逻辑
BST转特殊最大堆问题的疑问
题目要求
给定一个二叉搜索树(BST),将其转换为特殊Max Heap,需满足:所有节点的左子树所有值小于右子树所有值,该条件适用于转换后的所有节点。
查看的解决方案代码
class Solution { public static ArrayList<Integer> list=new ArrayList<>(); static int i=0; public static void InOrderTraversal(Node root){ if(root == null) return ; InOrderTraversal(root.left); list.add(root.data); InOrderTraversal(root.right); } public static void PostOrderTraversal(Node root){ if(root == null )return; PostOrderTraversal(root.left); PostOrderTraversal(root.right); root.data= list.get(i); i++; } public static void convertToMaxHeapUtil(Node root) { InOrderTraversal(root); PostOrderTraversal(root); } }
我疑惑的点在于:这段代码既没有添加也没有删除节点,只是修改了节点的数值,怎么就能把BST转换成符合要求的Max Heap?
测试用例示例
输入BST
3 / \ 1 5 \ / \ 2 4 6 \ 7
预期Max Heap输出
7 / \ 3 6 / \ / \ 1 2 4 5
我完全搞不懂这段代码在这个测试用例上是如何运行得到预期结果的。
题目驱动代码
//{ Driver Code Starts //Initial Template for Java import java.util.LinkedList; import java.util.Queue; import java.io.*; import java.util.*; class Node{ int data; Node left; Node right; Node(int data){ this.data = data; left=null; right=null; } } class Tree { static Node buildTree(String str){ if(str.length()==0 || str.charAt(0)=='N'){ return null; } String ip[] = str.split(" "); // Create the root of the tree Node root = new Node(Integer.parseInt(ip[0])); // Push the root to the queue Queue<Node> queue = new LinkedList<>(); queue.add(root); // Starting from the second element int i = 1; while(queue.size()>0 && i < ip.length) { // Get and remove the front of the queue Node currNode = queue.peek(); queue.remove(); // Get the current node's value from the string String currVal = ip[i]; // If the left child is not null if(!currVal.equals("N")) { // Create the left child for the current node currNode.left = new Node(Integer.parseInt(currVal)); // Push it to the queue queue.add(currNode.left); } // For the right child i++; if(i >= ip.length) break; currVal = ip[i]; // If the right child is not null if(!currVal.equals("N")) { // Create the right child for the current node currNode.right = new Node(Integer.parseInt(currVal)); // Push it to the queue queue.add(currNode.right); } i++; } return root; } static void postOrder(Node root) { if(root == null) return; postOrder(root.left); postOrder(root.right); System.out.print(root.data+" "); } public static void main (String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int t=Integer.parseInt(br.readLine()); while(t > 0){ String s = br.readLine(); Node root = buildTree(s); Solution g = new Solution(); g.convertToMaxHeapUtil(root); postOrder(root); System.out.println(); t--; } } } // } Driver Code Ends
代码工作原理解释
核心在于题目对特殊Max Heap的定义,结合BST的特性:
- BST中序遍历特性:BST的中序遍历会得到严格递增的序列。测试用例输入的BST中序遍历结果是:
[1,2,3,4,5,6,7]。 - 特殊Max Heap的匹配逻辑:题目要求每个节点左子树所有值 < 右子树所有值,同时Max Heap要求父节点值是子树中的最大值。而后序遍历(左→右→根)的顺序,刚好能和递增序列对应:左子树先赋值较小的数,右子树赋值较大的数,根节点最后赋值最大的数,完美满足所有条件。
- 代码执行流程:
- 第一步中序遍历BST,把递增序列存入list;
- 第二步后序遍历原树,按顺序将list的值赋值给每个节点。树的结构完全不变,只是数值被重新分配。
拿测试用例举例:
- 中序遍历得到
[1,2,3,4,5,6,7] - 后序遍历原树的节点顺序是:1 → 2 → 3 →4 →5 →6 →7
- 按顺序赋值后,每个节点的数值对应list的位置:
- 叶子节点1赋值1,叶子节点2赋值2,根节点3赋值3;
- 叶子节点4赋值4,叶子节点5赋值5,节点6赋值6;
- 最终根节点7赋值7;
这样就得到了预期的Max Heap结构,完全符合题目要求。
内容的提问来源于stack exchange,提问作者shivam
相关产品推荐
相关产品推荐

