题目描述
谈到二叉搜索树,那就得考虑考虑中序遍历啦~ 这道题对中序遍历的理解提升很有好处!
思路 && 代码
1. 非原地算法
最简单的做法,依赖ArrayList,但是不满足原地 算法的要求 只要通过中序遍历,把树上结点存储到ArrayList中,再通过下标进行操作即可。
class Solution { ArrayList < Node > list = new ArrayList < > ( ) ; public Node treeToDoublyList ( Node root) { if ( root == null ) { return null ; } 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 ) ; } public void midErgodic ( 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 是全局变量
class Solution { Node first, pre; public Node treeToDoublyList ( Node root) { if ( root == null ) { return null ; } dfs ( root) ; first. left = pre; pre. right = first; return first; } public void dfs ( Node cur) { if ( cur == null ) { return ; } dfs ( cur. left) ; if ( pre != null ) { pre. right = cur; } else { first = cur; } cur. left = pre; pre = cur; dfs ( cur. right) ; }
}
二刷
class Solution { Node head = null ; Node pre = null ; public Node treeToDoublyList ( Node root) { if ( root == null ) { return null ; } dfs ( root) ; head. left = pre; pre. right = head; return head; } public void dfs ( 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) ; }
}