题目:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
题解:
class Solution {
Node head, pre;
public Node treeToDoublyList(Node root) {
if(root==null) return null;
dfs(root);
pre.right = head;
head.left =pre;//进行头节点和尾节点的相互指向,这两句的顺序也是可以颠倒的
return head;
}
public void dfs(Node cur){
if(cur==null) return;
dfs(cur.left);
if(pre==null) head = cur;//pre用于记录双向链表中位于cur左侧的节点,即上一次迭代中的cur,当pre==null时,cur左侧没有节点,即此时cur为双向链表中的头节点
else pre.right = cur;//反之,pre!=null时,cur左侧存在节点pre,需要进行pre.right=cur的操作。
cur.left = pre;//pre是否为null对这句没有影响,且这句放在上面两句if else之前也是可以的。
pre = cur;//pre指向当前的cur
dfs(cur.right);//全部迭代完成后,pre指向双向链表中的尾节点
}
}
//by:krahets
解题思路:
本文解法基于性质:二叉搜索树的中序遍历为递增序列 。
将二叉搜索树 转换成一个 “排序的循环双向链表” ,其中包含三个要素:
排序链表: 节点应从小到大排序,因此应使用 中序遍历 “从小到大”访问树的节点;
双向链表: 在构建相邻节点(设前驱节点 prepre ,当前节点 curcur )关系时,不仅应 pre.right = cur,也应 cur.left = pre
循环链表:设链表头节点 head 和尾节点 tail ,则应构建 head.left = tail和 tail.right = head
// 打印中序遍历
void dfs(TreeNode root) {
if(root == null) return;
dfs(root.left); // 左
System.out.println(root.val); // 根
dfs(root.right); // 右
}
心得经验:
上面是中序遍历的大概历程,以上的都是在中序遍历的框架里进行拓展
记住,当在java中进行这种类似于树中的节点或者链表中节点进行交换或者赋值时:
有这样的规则:
r=r—>next
要让r往后进一步,那么就要用到这样的形式
pre.next = cur
cur.pre = pre
要让其建立起双链表的形式,就是pre向后指向cur,cur向前指向pre,那么就是这样的形式,=的前后就是其指向的顺序