import java.util.*;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
// 封装结构 - 该子树的最大结点和最小结点
// 这里不涉及到新建TreeNode结点,只用作记录已存在的TreeNode结点
public class Info {
// 该子树的最大结点
TreeNode max;
// 该子树的最小结点
TreeNode min;
public Info(TreeNode max, TreeNode min) {
this.max = max;
this.min = min;
}
}
// 主方法
public TreeNode Convert(TreeNode pRootOfTree) {
// 根据左程云老师讲的【二叉树递归套路】,先弄明白三件事
// 1.我要干什么:
// 令root.left <-> 【左子树】的【最大结点】
// 令root.right <-> 【右子树】的【最小结点】
// 2.我需要什么信息:
// 综上所述,我需要左右子树的【最小结点】和【最大结点】,可以把它们【封装】进一个数据结构中,方便递归函数的return
// 3.我如何利用两个子树的信息加工出来我的信息:
// 根据二叉搜索树的性质:
// root的【最大结点】 = 【右子树】的【最大结点】 或者 【root】
// root的【最小结点】 = 【左子树】的【最小结点】 或者 【root】
// 调用递归函数生成双向链表,并返回这个双向链表的最左头结点
Info resultInfo = process(pRootOfTree);
return resultInfo.min;
}
// 递归序遍历二叉树函数 - 返回以root为根结点的子树的最大结点和最小结点
public Info process(TreeNode root) {
// 递归出口
if (root == null) {
// 当结点为空时,说明这一子树的max和min都是null
return new Info(null, null);
}
// 记录左子树和右子树的最小结点和最大结点
Info leftInfo = process(root.left);
Info rightInfo = process(root.right);
// 拿到左右子树的Info后做两件事:
// 1.令root.left <-> 【左子树】的【最大结点】;root.right <-> 【右子树】的【最小结点】
root.left = leftInfo.max;
if (leftInfo.max != null) {
leftInfo.max.right = root;
}
root.right = rightInfo.min;
if (rightInfo.min != null) {
rightInfo.min.left = root;
}
// 2.生成自己的Info信息并返回
TreeNode myMax = (rightInfo.max != null) ? rightInfo.max : root;
TreeNode myMin = (leftInfo.min != null) ? leftInfo.min : root;
return new Info(myMax, myMin);
}
}