描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示:
数据范围:输入二叉树的节点数 0≤n≤10000≤n≤1000,二叉树中每个节点的值0≤val≤10000≤val≤1000
要求:空间复杂度O(1)(即在原树上操作),时间复杂度 O(n)。
注意:
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。
2.返回链表中的第一个节点的指针。
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构。
4.你不用输出双向链表,程序会根据你的返回值自动打印输出。
输入描述:
二叉树的根节点。
返回值描述:
双向链表的其中一个头节点。
思路分析
要将BST转换为排序的双向链表,我们可以利用BST的中序遍历的特性。中序遍历的顺序访问BST的节点,可以保证节点的值是按升序排列的。
具体步骤如下:
- 使用递归进行中序遍历。
- 在中序遍历的过程中调整节点的指针,将当前节点的左指针指向前一个节点,右指针指向后一个节点。
- 用一个全局变量
prev
记录中序遍历过程中前一个节点,用另一个全局变量head
记录双向链表的头节点。
代码实现
public class Solution {
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
private TreeNode prev = null;
private TreeNode head = null;
private void inOrderConvert(TreeNode node) {
if (node == null) return;
// 递归遍历左子树
inOrderConvert(node.left);
// 处理当前节点
if (prev == null) {
head = node; // 当前节点是最左边的节点,即双向链表的头节点
} else {
prev.right = node; // 将前一个节点的右指针指向当前节点
node.left = prev; // 将当前节点的左指针指向前一个节点
}
prev = node; // 更新前一个节点为当前节点
// 递归遍历右子树
inOrderConvert(node.right);
}
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null){
return null;
}
inOrderConvert(pRootOfTree);
return head;
}
}