递归
思路:
- 将二叉搜索树中原先指向左节点的指针转化为双向链表中指向前一个结点的指针。
- 将二叉搜索树中原先指向右节点的指针转化为双向链表中指向后一个节点的指针。
要求转换后的双向链表是排序的所以可以使用中序遍历。当遍历到根节点时如下图所示,将树分为三部分:- 根节点10
- 根节点为6的左子树
- 根节点为14的右子树
将10和左子树的最大节点8连接,与右子树的最小节点连接。由于需要先将左右子树转化为双向链表,然而这又是处理相同的问题所以可以使用递归
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
//java函数为值传递,需要使用全局变量
private Node lastNodeInList = null;
private Node pHeadOfList = null;
public Node treeToDoublyList(Node root) {
if(root == null) return null;
convertNode(root);
pHeadOfList = lastNodeInList;
//lastNodeInList指向双向链表尾部节点
while(pHeadOfList != null && pHeadOfList.left != null){
pHeadOfList = pHeadOfList.left;
}
//头尾相连
lastNodeInList. right = pHeadOfList;
pHeadOfList.left = lastNodeInList;
return pHeadOfList;
}
private void convertNode(Node pNode){
if(pNode == null)
return;
Node current = pNode;
if(current.left != null)
convertNode(current.left);
current.left = lastNodeInList;
if(lastNodeInList != null)
lastNodeInList.right = current;
lastNodeInList = current;
if(current.right != null)
convertNode(current.right);
}
}
上面的解法先使用一个全局变量lastNodeInList
找到双向链表的尾节点然后循环找到头节点然后头尾相连。
下面这种解法直接在递归时找到双向链表头节点,然后头尾相连
class Solution {
private Node lastNodeInList = null;
private Node pHeadOfList = null;
public Node treeToDoublyList(Node root) {
if(root == null) return null;
convertNode(root);
lastNodeInList. right = pHeadOfList;
pHeadOfList.left = lastNodeInList;
return pHeadOfList;
}
private void convertNode(Node pNode){
if(pNode == null)
return;
Node current = pNode;
if(current.left != null)
convertNode(current.left);
current.left = lastNodeInList;
if(lastNodeInList != null)
lastNodeInList.right = current;
else pHeadOfList = current;
lastNodeInList = current;
if(current.right != null)
convertNode(current.right);
}
}