目录
题目要求是将一个二叉搜索树转换成一个排序的双向链表,条件是不能创建任何新的节点,只能调整树中节点指针的指向。这意味着我们需要在原地进行转换,利用树的节点构建链表。
本篇题解完全参照官方,总结了一些个人感悟。
二叉搜索树是一种特殊的二叉树,满足以下性质:每个节点的值都大于其左子树中任何节点的值,且小于其右子树中任何节点的值。这使得BST在进行中序遍历时输出的是一个有序序列。
双向链表是一种链式数据结构,其中每个节点包含数据部分和两个指向前后节点的链接。这种结构允许双向遍历:从头到尾,也可以从尾到头。
中序遍历是一种遍历二叉树的方式,遍历顺序是左-根-右。对于BST,这种遍历方式输出的节点序列是有序的。
利用BST的中序遍历特性,可以按顺序访问树的所有节点。在访问每个节点时,我们将其加入到双向链表中。
pre
)存在,则设置pre.right = current
,并设置current.left = pre
。public class Solution {
//返回的第一个指针,即为最小值,先定为null
public TreeNode head = null;
//中序遍历当前值的上一位,初值为最小值,先定为null
public TreeNode pre = null;
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null)
//中序递归,叶子为空则返回
return null;
//首先递归到最左最小值
Convert(pRootOfTree.left);
//找到最小值,初始化head与pre
if(pre == null){
head = pRootOfTree;
pre = pRootOfTree;
}
//当前节点与上一节点建立连接,将pre设置为当前值
else{
pre.right = pRootOfTree;
pRootOfTree.left = pre;
pre = pRootOfTree;
}
Convert(pRootOfTree.right);
return head;
}
}
在双向链表中,尾节点是最后一个节点,即没有后继节点的节点。在从二叉搜索树转换成的双向链表中,尾节点是树中值最大的节点,因为二叉搜索树的特性决定了任何节点的右子树包含的值都大于该节点,所以最右侧的节点是值最大的。
left
和right
属性left
属性:尾节点的left
指向双向链表中的前一个节点。在二叉搜索树转换的上下文中,这个前一个节点是中序遍历中当前节点的前驱,即二叉树中值第二大的节点。right
属性:由于尾节点是链表的最后一个节点,所以它的right
属性应该是null
,表示没有后继节点。在将二叉搜索树转换为双向链表的过程中:
pre
变量将指向这个尾节点。然而,这个信息在方法结束后通常不可用,因为pre
不是方法的返回值。如果在转换完成后需要找到尾节点,可以从头节点开始遍历链表,直到到达末尾。例如:
TreeNode tail = head;
while (tail.right != null) {
tail = tail.right;
}
在这个遍历过程结束后,tail
将指向双向链表的尾节点。
尾节点在某些应用场景中非常重要,比如在需要从双向链表的末尾开始逆向遍历时。由于尾节点没有后继,这使得它成为链表逆向遍历的起点。
总之,尾节点在由二叉搜索树转换成的双向链表中扮演着链表最后一个元素的角色,其left
指针指向前一个节点,而right
指针为null
。在实际的转换算法实现中,尾节点并没有被特别标记或返回,但可以通过遍历从头节点找到。
递归是此问题解决的关键。每次递归调用处理树的一小部分(一个子树),最终构建出整个链表。