题目描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路:二叉搜索树中,每个节点都有两个分别指向其左右子树的指针,左子树的节点值总是小于父节点的值,右子树的节点值总是大于父节点的值。
在双向链表中,每个节点也有两个指针,它们分别指向前一个节点和后一个节点。
在转换成排序双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向下一个节点的指针。由于链表要求有序,则可借助二叉树中序遍历。中序遍历算法的特点是从小到大访问节点。当遍历访问到根节点时,假设根节点的左侧已经处理好,中只需将根节点与上次访问的最近节点(左子树最大节点)的指针连接好即可,进而更新当前链表的最后一个节点指针。同时中序遍历过程正好是转换成链表的过程,可采用递归方法。
代码:
/**
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 p = left;
//定位到左子树双链表最后一个节点
while(p != null && p.right != null){
p = p.right;
}
//如果左子树链表不为空的话,将当前root追加到左子树链表
if(left != null){
p.right = pRootOfTree;
pRootOfTree.left = p;
}
//将右子树构造成双链表,并返回表头节点
TreeNode right = Convert(pRootOfTree.right);
//如果右子树链表不为空的话,追加到root节点后
if(right != null){
right.left = pRootOfTree;
pRootOfTree.right = right;
}
return left == null ? pRootOfTree : left;
}
}