题目描述:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
思路分析:
根据题目,要将一颗二插搜索树改为排序的双向链表,根据二插搜索树的性质,要用中序遍历解题。
中序遍历:
dfs(root.left);//左
print(root);//根
dfs(dfs.rigt);//右
1)该题可以设置2个指针pre和curr,curr指向当前结点,pre指向前驱,先dfs(root.leeft);
2)直到root==null后, 此时pre=null,curr指向最左边的结点,令head=curr,即该结点为转换为双链表后的头结点。
3)然后改变对应指针的方向。
4)最后dfs(root.right);
5)将首尾结点连接起来。
参考代码:
//定义结点Node
class Node{
int val;
Node left;
Node right;
public Node() {}
public Node(int _val) { val = _val;}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
}
//定义成员变量head和pre
private Node head;
private Node pre;
public Node treeToDoublyList(Node root) {
if(root == null)return root;
dfs(root);
head.left = pre;
pre.right = head;
return head;
}
//核心方法
public void dfs(Node curr){
if(curr == null)return;//递归结束条件
dfs(curr.left);
if(pre == null)head = curr;//pre为null时,curr指向的就是将来的head结点
else pre.right= curr;
curr.left= pre;
pre = curr;
dfs(curr.right);
}
小结:
-
该题力扣题目要求改为双向循环链表,而牛客题目要求改为循环链表就行。
-
关键代码:
curr.left = pre;
pre.right = curr;
(完)