题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
要求不能创建任何新的结点,只能调整树中结点指针的指向。
方法一: 使用递归
第一种方法是用递归去操作. 每一次递归的核心思想:
找到左子树的最右节点, 和右子树的最左节点, 与根节点进行连接.
然后对左子树和右子树做相同操作即可.
public TreeNode convertRecursive(TreeNode pRootOfTree) {
if (pRootOfTree == null) return null;
if (pRootOfTree.left == null && pRootOfTree.right == null) return pRootOfTree;
TreeNode left = convertRecursive(pRootOfTree.left);
TreeNode curNode = left;
// 找到左子树最右节点
while (curNode != null && curNode.right != null) {
curNode = curNode.right;
}
if (left != null) {
pRootOfTree.left = curNode;
curNode.right = pRootOfTree;
}
TreeNode right = convertRecursive(pRootOfTree.right);
curNode = right;
// 找到右子树最左节点
while (curNode != null && curNode.left != null) {
curNode = curNode.left;
}
if (right != null) {
pRootOfTree.right = curNode;
curNode.left = pRootOfTree;
}
// 判断左子树为空的情况
return left == null ? pRootOfTree : left;
}
方法二: 借助数组
二叉搜索树的中序遍历序列就是二叉树的递增序列.
根据这一思想, 我们可以先把BST的按递增顺序的节点(中序遍历序列)用顺序表存起来.
之后直接按顺序进行双向连接即可.
返回值使用list.get(0)即可.(对应最小节点)
/*
思路: 使用ArrayList, 将中序遍历序列存储起来, 再依次进行连接即可.
*/
public TreeNode convertByArrayList(TreeNode root) {
if (root == null) return null;
// 获得中序遍历序列
ArrayList<TreeNode> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
// 压入左子树
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
list.add(cur);
cur = cur.right;
}
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i) == null) continue;
list.get(i).right = list.get(i+1);
list.get(i+1).left = list.get(i);
}
return list.get(0);
}