/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
};
*/classSolution{ArrayList<Node> list =newArrayList<>();publicNodetreeToDoublyList(Node root){if(root ==null){returnnull;}// 先中序遍历存储结点midErgodic(root);// 接着逐个改变指针for(int i =0; i < list.size(); i++){if(i ==0){
list.get(i).left = list.get(list.size()-1);}else{
list.get(i).left = list.get(i -1);}if(i == list.size()-1){
list.get(i).right = list.get(0);}else{
list.get(i).right = list.get(i +1);}}return list.get(0);}publicvoidmidErgodic(Node root){if(root ==null){return;}midErgodic(root.left);
list.add(root);midErgodic(root.right);}}
2. 原地算法
和1异曲同工,但是相对更加巧妙!
Node first:存储最左边的**“首位”**结点,用于最后的处理
Node pre:在递归中辅助使用,递归结束后指向**“末尾”**结点
同样是中序遍历,要注意好 cur 、pre 的处理
cur 是局部变量;pre、first 是全局变量
// 很经典的中序遍历题~classSolution{Node first, pre;publicNodetreeToDoublyList(Node root){// 空树情况if(root ==null){returnnull;}// 开启dfsdfs(root);// dfs结束,此时 pre 就是最右边(最大)节点.// 进行头 - 尾节点的处理
first.left = pre;
pre.right = first;return first;}publicvoiddfs(Node cur){if(cur ==null){return;}// 中序dfs(cur.left);// right 的处理,没有 pre 节点的是 firstif(pre !=null){
pre.right = cur;}else{
first = cur;}// left 的处理
cur.left = pre;// 维护 pre 结点
pre = cur;dfs(cur.right);}}
二刷
中序遍历 + 全局变量
classSolution{Node head =null;Node pre =null;publicNodetreeToDoublyList(Node root){if(root ==null){returnnull;}dfs(root);
head.left = pre;
pre.right = head;return head;}publicvoiddfs(Node root){if(root ==null){return;}treeToDoublyList(root.left);if(pre ==null){
head = root;}else{
pre.right = root;}
root.left = pre;
pre = root;treeToDoublyList(root.right);}}
文章目录题目描述思路 && 代码1. 非原地算法2. 原地算法题目描述谈到二叉搜索树,那就得考虑考虑中序遍历啦~这道题对中序遍历的理解提升很有好处!思路 && 代码1. 非原地算法最简单的做法,依赖ArrayList,但是不满足原地算法的要求只要通过中序遍历,把树上结点存储到ArrayList中,再通过下标进行操作即可。/*// Definition for a Node.class Node { public int val;