问题
将二叉搜索树转化为双向链表
代码
/*
* 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
* 要求不能创建任何新的结点,只能调整树中结点指针的指向。
*/
public class ConvertBinaryTreeToDoublyLinkedList {
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null ||
(pRootOfTree.left == null && pRootOfTree.right == null)) {
return pRootOfTree;
}
//拿到左子树(展开成链表的形式)的头节点,并找到左子树的末尾节点
TreeNode left = Convert(pRootOfTree.left);
TreeNode p = left;
while(p != null && p.right != null) {
p = p.right;
}
//将根节点接上左子树的末尾节点
if(p != null) {
p.right = pRootOfTree;
pRootOfTree.left = p;
}
//拿到右子树的头节点
TreeNode right = Convert(pRootOfTree.right);
//将根节点接上右子树的头节点
if(right != null) {
pRootOfTree.right = right;
right.left = pRootOfTree;
}
return left == null ? pRootOfTree : left;
}
//改进法二:左子树最后一个叶子节点必为左子树的末尾节点,可以省去遍历左子树的末尾节点
TreeNode leftLast = null;
public TreeNode Convert2(TreeNode pRootOfTree) {
if(pRootOfTree == null) {
return pRootOfTree;
}
if(pRootOfTree.left == null && pRootOfTree.right == null) {
leftLast = pRootOfTree;
return pRootOfTree;
}
//拿到左子树的头节点,并将根节点接上左子树的末尾节点
TreeNode left = Convert2(pRootOfTree.left);
if(left != null && leftLast != null) {
leftLast.right = pRootOfTree;
pRootOfTree.left = leftLast;
}
//拿到右子树的头节点
TreeNode right = Convert2(pRootOfTree.right);
//将根节点接上右子树的头节点
if(right != null) {
pRootOfTree.right = right;
right.left = pRootOfTree;
}
return left == null ? pRootOfTree : left;
}
public static void main(String[] args) {
TreeNode root1 = new TreeNode(1);
root1.left = new TreeNode(2);
root1.right = new TreeNode(3);
root1.left.left = new TreeNode(4);
root1.left.right = new TreeNode(5);
root1.right.left = new TreeNode(6);
root1.right.right = new TreeNode(7);
TreeNode node = new ConvertBinaryTreeToDoublyLinkedList().Convert2(root1);
while(node != null) {
System.out.print(node.val + " ");
node = node.right;
}
}
}