题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
/**
public class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;}}
*/
public class Solution {public TreeNode Convert(TreeNode pRootOfTree) {if(pRootOfTree==null)return null;if(pRootOfTree.left==null&&pRootOfTree.right==null)return pRootOfTree;// 1.将左子树构造成双链表,并返回链表头节点TreeNode left = Convert(pRootOfTree.left);TreeNode p = left;// 2.定位至左子树双链表最后一个节点while(p!=null&&p.right!=null){p = p.right;}// 3.如果左子树链表不为空的话,将当前root追加到左子树链表if(left!=null){p.right = pRootOfTree;pRootOfTree.left = p;}// 4.将右子树构造成双链表,并返回链表头节点TreeNode right = Convert(pRootOfTree.right);// 5.如果右子树链表不为空的话,将该链表追加到root节点之后if(right!=null){right.left = pRootOfTree;pRootOfTree.right = right;}return left!=null?left:pRootOfTree; }
}
遇到递归,就需要举例进行分析,不然你根本看不到递归在干嘛!
假设有如下一棵二叉搜索树:
执行下面这段代码:
一直到节点1停止,当前left=节点1:
因为节点1没有右孩子,所以继续往下:
将p的父节点pRootOfTree,加到p的右节点, 将p放到pRootOfTree左结点,这样就形成了双向链表;
当前双向链表的结构:
继续往下
节点6进入递归:
来到当前位置:
节点6的左孩子节点4进入递归:
因为节点4没有左右孩子,返回节点4,left=节点4,由于节点4没有右孩子,执行到:
将p的父节点pRootOfTree加到p的右孩子上面,将p 加到pRootOfTree的左孩子上面;
结构如下图所示:
继续往下:
将pRootOfTree节点(6)的右孩子放入到递归中:
节点7没有左右孩子,直接返回节点7,right=节点7;
这样的话,就可以直接将节点7加入到双向链表中:
结构如下图所示:
继续往下
左结点left是4哦,这样别忘了,然后返回:
当前位置是left=1,pRootOfTree=3,(递归是真的有意思) ,到一下
将right加入链表中之后,的结构:
然后返回:
后面的代码我就我具体分析了,后面基本上就是将根结点加入到该左孩子链表的尾部,然后一样的方式去递归右孩子双向链表,把根结点放到链表头就可以了;
总结:递归是二叉树问题的核心,递归写起来简单,理解起来难,而且要一步步讲出来的话,越描述到下面,越难描述,所以后面我就没有继续描述了,因为递归中的一步步回归是真的麻烦.
永远要记住:不积跬步无以至千里!