题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
方法一:在转换的时候,原先指向左子节点的指针调整为链表中指向前一节点的指针,原先指向右子节点的指针调整为链表中指向后一节点的指针。先递归转换左右子树,然后把左右子树排序转换成排序后的双向链表再和根节点连接起来。
import java.util.ArrayList;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
//原先指向左子节点的指针调整为链表中指向前一节点的指针
//原先指向右子节点的指针调整为链表中指向后一节点的指针
//把左右子树排序转换成排序后的双向链表再和根节点连接起来
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null){
return null;
}
if(pRootOfTree.left==null && pRootOfTree.right==null){
return pRootOfTree;
}
//先处理左子树,相当于与把左子树已经完整的转换成双向链表(得到左子树链表的头结点)
TreeNode left=Convert(pRootOfTree.left);
//将左子树转换成的双向链表和根节点 连接起来
TreeNode leftT=left;
//先到链表的最末端
while(leftT!=null && leftT.right!=null){
leftT=leftT.right;
}
if(leftT!=null)
{
leftT.right=pRootOfTree;
pRootOfTree.left=leftT;
}
//递归处理右子树(得到右子树链表的头结点)
TreeNode right=Convert(pRootOfTree.right);
if(right!=null){
pRootOfTree.right=right;
right.left=pRootOfTree;
}
return left!=null?left:pRootOfTree;
}
}
方法二:中序遍历二叉搜索树,将其节点存放在数组中,然后再次遍历数组,改变其左右指针。
import java.util.ArrayList;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
//1.递归+数组
//中序遍历一遍二叉搜索树,将其保留在数组中
//遍历数组,更改左右
//时间复杂度是o(n),空间复杂度是o(n)
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null)
{
return null;
}
ArrayList<TreeNode> list=new ArrayList<>();
ArrayList<TreeNode> succ=inT(pRootOfTree,list);
return change(succ);
}
public ArrayList<TreeNode> inT(TreeNode node,ArrayList<TreeNode> list){
if(node.left!=null)
{
inT(node.left,list);
}
list.add(node);
if(node.right!=null){
inT(node.right,list);
}
return list;
}
public TreeNode change(ArrayList<TreeNode> list){
for(int i=0;i<list.size()-1;i++)
{
list.get(i).right=list.get(i+1);
list.get(i+1).left=list.get(i);
}
return list.get(0);
}
}