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 head = null;
TreeNode pre = null;
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null){
return null;
}
//找到最左节点
Convert(pRootOfTree.left);
//初始化双向链表的头指针和前向指针
if(pre==null){
head=pRootOfTree;
pre=pRootOfTree;
}else{
//完成链表指向
pre.right = pRootOfTree;
pRootOfTree.left = pre;
pre = pRootOfTree;
}
//处理右子树
Convert(pRootOfTree.right);
//只有当处理完最右节点后才返回双向链表头
return head;
}
}
方法一:递归
由于二叉搜索树遍历得到升序序列的结果和中序遍历一样,所以采用中序递归。题目要求不能创建新结点,但需要一个指针指向新双向链表,还需要一个用来指定当前节点的前驱节点的指针。链表建立过程:
首先,找到最左边的节点,此时需要给两个指针初始化。
其次,从第二个节点开始,先指定该节点的前驱,再指定前驱结点的后继,然后更新前驱指针指向当前节点。
然后,遍历右子树,重复上述步骤。
最后,当最右边的节点,即最大的节点处理完后,返回双向链表的头结点。
方法二:栈
与中序遍历的栈实现方法一样,不同的就是需要加上递归中所说的两个指针,另外需要一个标识最左边节点的标记。
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 {
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null){
return null;
}
TreeNode head = null;
TreeNode pre = null;
Stack<TreeNode> s = new Stack<TreeNode>();
//区分是否是最左边的结点,用于初始化两个指针
boolean isFirst = true;
while(pRootOfTree!=null||!s.isEmpty()){
//向左遍历,直到没有左节点
while(pRootOfTree!=null){
s.push(pRootOfTree);
pRootOfTree = pRootOfTree.left;
}
pRootOfTree = s.pop();
if(isFirst){
head = pRootOfTree;
pre = pRootOfTree;
isFirst = false;
}else{
pre.right = pRootOfTree;
pRootOfTree.left = pre;
pre = pRootOfTree;
}
pRootOfTree = pRootOfTree.right;
}
//返回双向链表头
return head;
}
}


京公网安备 11010502036488号