题目:
输入一棵二叉搜索树,将该二叉搜索树转换为一个排序的双向链表。要求:不能创建任何新的结点,只能调整树中结点指针的指向。如下图:
解法1(非递归):
思想:二叉搜索树的中序遍历是一个有序的数组,在中序遍历的时候,用 Pre 指针保存前一个节点,当访问到当前节点的时候,将 Pre 节点右指针,指向当前节点,当前节点的左指针指向 Pre。 这样中序遍历完二叉搜索树,就产生了一个双向链表。
public TreeNode ConvertWithStack(TreeNode pRootOfTree) {
if(pRootOfTree==null)
return null;
//如果根节点为 null 返回 null 否则当前节点 cur 指向根节点 pRootOfTree
TreeNode cur=pRootOfTree;
TreeNode pre=null;
//pre 用于指向当前节点的前一个节点,开始时为 null。
Stack<TreeNode> stack=new Stack<TreeNode>();
while(!stack.isEmpty()||cur!=null)
{
//将左子树上的节点入栈
while(cur!=null)
{
stack.push(cur);
cur=cur.left;
}
//如果已经到了树的最左边,则将栈中的节点出栈。
cur=stack.pop();
if(pre==null)
{
//刚开始的时候 pre==null 将最左边的 节点赋值给 pRootOfTree。当前节点复值给pre
pRootOfTree=cur;
pre=cur;
}
else {
pre.right=cur;
cur.left=pre;
pre=cur;
//前一个节点的右指针指向 cur 当前节点,当前节点的左指针指向 前一个节点pre
}
cur=cur.right;
}
return pRootOfTree;
}
解法2(递归)
可以直接用中序遍历的递归来做,思路和上面一样。
public class TreeConvert {
TreeNode tail=null;
TreeNode head=null;
//head 保存链表的头节点,tail 保存当前节点的前一个节点。
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null)
{
return null;
}
Convert(pRootOfTree.left);
if(head==null)
{
head=pRootOfTree;
tail=pRootOfTree;
}
else {
pRootOfTree.left=tail;
tail.right=pRootOfTree;
tail=pRootOfTree;
}
Convert(pRootOfTree.right);
return head;
}
}