题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中节点指针的指向。eg,图所示
分析:在二叉搜索树中,左子结点的值总是小于父结点的值,右子结点的值总是大于父结点的值,在转换过程中,原先指向左子结点的指针调整为链表中指向前一个结点的指针,原先指向右子结点的指针调整为链表中指向后一个结点的指针。
代码,参考自牛客大神和剑指offer
//递归:左子树构成双链表,并返回链表头结点,定位至左子树双链表最后一个结点 //如果左子树链表不为空,将当前root追加到左子树链表 //将右子树构成双链表,并返回头结点 //若右子树不为空,将该链表追加到root结点之后 //根据左子树链表是否为空确定返回的结点 public class wr27binaryTreeList { public static TreeNode Convert(TreeNode root){ if(root==null){ return null; } if(root.left==null && root.right==null){ return root; } // 左子树构成双向链表,并返回链表头结点 TreeNode left=Convert(root.left); TreeNode temp=left; while(temp!=null &&temp.right!=null){//定位至左子树双链表最后一个结点 temp=temp.right; } if(left!=null){ temp.right=root; root.left=temp; } //将右子树构成双链表,并返回头结点 TreeNode right=Convert(root.right); if(right!=null){ right.left=root; root.right=right; } return left==null?root:left; } public static void main(String[] args) { // TODO Auto-generated method stub TreeNode node0=new TreeNode(10); TreeNode node1=new TreeNode(6); TreeNode node2=new TreeNode(14); TreeNode node3=new TreeNode(4); TreeNode node4=new TreeNode(8); TreeNode node5=new TreeNode(12); TreeNode node6=new TreeNode(16); node0.left=node1; node0.right=node2; node1.left=node3; node1.right=node4; node2.left=node5; node2.right=node6; TreeNode newHead=Convert(node0); System.out.println(newHead.val); } }
改进,可用一个变量记录已经转换好的链表的最后一个结点
public class wr27better { // 增加一个变量记录已将转换好的链表的最后一个结点,即值最大的结点 public static TreeNode theMax=null; public static TreeNode Convert(TreeNode root){ if(root==null){ return null; } if(root.left==null && root.right==null){ theMax=root; return root; } // 左子树构成双向链表,并返回链表头结点 TreeNode left=Convert(root.left); TreeNode temp=left; if(left!=null){ theMax.right=root; root.left=theMax; } theMax=root; //将右子树构成双链表,并返回头结点 TreeNode right=Convert(root.right); if(right!=null){ right.left=root; root.right=right; } return left==null?root:left; } }