题目叙述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
方法一:
- 先对二叉树进行中序遍历并且将其遍历的所有结点进行保存
- 遍历保存好的中序遍历序列然后进行修改其左右指向,这里需要注意的是第一个结点和尾结点需要单独处理。对于双向链表来说,第一个结点没有前指向,认为指向为空,尾结点没有后指向,认为指向为空。
import java.util.ArrayList;
//import java.util.List;
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
//首先得是中序遍历
//使用一个arraylist进行保存中序遍历的节点
if (pRootOfTree==null) return null;
if (pRootOfTree.left == null && pRootOfTree.right==null) return pRootOfTree;
ArrayList<TreeNode> lis = new ArrayList<>();
TraverseMid(pRootOfTree, lis);
//处理第一个节点,它只有右孩子指向
lis.get(0).right = lis.get(1);
//处理中间的节点
for(int i=1;i<lis.size()-1;i++){
lis.get(i).left = lis.get(i-1);
lis.get(i).right = lis.get(i+1);
}
//处理最后一个节点,它只有左孩子指向
lis.get(lis.size()-1).left = lis.get(lis.size()-2);
return lis.get(0);
}
public void TraverseMid(TreeNode pRootOfTree, ArrayList lis){
if(pRootOfTree == null) return;
TraverseMid(pRootOfTree.left, lis);
lis.add(pRootOfTree);
TraverseMid(pRootOfTree.right, lis);
}
}
方法二:
参考:主要是采用递归的思想,左右子树分别考虑然后再拼接,中间连接结点是原始二叉搜索数的根节点。主要思想还是,对于二叉搜索树来说,最左边的节点就是最小元素节点,最右边的节点就是最大元素节点。
链接:https://www.nowcoder.com/questionTerminal/947f6eb80d944a84850b0538bf0ec3a5?f=discussion
来源:牛客网
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;
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left = Convert(root.left);
TreeNode p = left;
// 2.定位至左子树双链表最后一个节点
while(p!=null&&p.right!=null){
p = p.right;
}
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if(left!=null){
p.right = root;
root.left = p;
}
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right = Convert(root.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if(right!=null){
right.left = root;
root.right = right;
}
return left!=null?left:root;
}