原地址:http://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
方法一:非递归版
解题思路:
1
.核心是中序遍历的非递归算法。
2
.修改当前遍历节点与前一遍历节点的指针指向。
import
java.util.Stack;
public
TreeNode ConvertBSTToBiList(TreeNode root) {
if
(root==
null
)
return
null
;
Stack<TreeNode>
stack =
new
Stack<TreeNode>();
TreeNode
p = root;
TreeNode
pre =
null
;
boolean
isFirst =
true
;
while
(p!=
null
||!stack.isEmpty()){
while
(p!=
null
){
stack.push(p);
p
= p.left;
}
p
= stack.pop();
if
(isFirst){
root
= p;
pre
= root;
isFirst
=
false
;
}
else
{
pre.right
= p;
p.left
= pre;
pre
= p;
}
p
= p.right;
}
return
root;
}
方法二:递归版
解题思路:
1
.将左子树构造成双链表,并返回链表头节点。
2
.定位至左子树双链表最后一个节点。
3
.如果左子树链表不为空的话,将当前root追加到左子树链表。
4
.将右子树构造成双链表,并返回链表头节点。
5
.如果右子树链表不为空的话,将该链表追加到root节点之后。
6
.根据左子树链表是否为空确定返回的节点。
public
TreeNode Convert(TreeNode root) {
if
(root==
null
)
return
null
;
if
(root.left==
null
&&root.right==
null
)
return
root;
TreeNode
left = Convert(root.left);
TreeNode
p = left;
while
(p!=
null
&&p.right!=
null
){
p
= p.right;
}
if
(left!=
null
){
p.right
= root;
root.left
= p;
}
TreeNode
right = Convert(root.right);
if
(right!=
null
){
right.left
= root;
root.right
= right;
}
return
left!=
null
?left:root;
}
方法三:改进递归版
解题思路:
思路与方法二中的递归版一致,仅对第
2
点中的定位作了修改,新增一个全局变量记录左子树的最后一个节点。
protected
TreeNode leftLast =
null
;
public
TreeNode Convert(TreeNode root) {
if
(root==
null
)
return
null
;
if
(root.left==
null
&&root.right==
null
){
leftLast
= root;
return
root;
}
TreeNode
left = Convert(root.left);
if
(left!=
null
){
leftLast.right
= root;
root.left
= leftLast;
}
leftLast
= root;
TreeNode
right = Convert(root.right);
if
(right!=
null
){
right.left
= root;
root.right
= right;
}
return
left!=
null
?left:root;
}