《编程之美》——二叉搜索树转换为排序双向链表

题目:
输入一棵二叉搜索树,将该二叉搜索树转换为一个排序的双向链表。要求不能创建任何新的节点,只能调整树中指针的指向。

分析与解法:
《编程之美》——二叉搜索树转换为排序双向链表_第1张图片
1、由于要求链表是有序的,可以借助二叉树中序遍历,因为中序遍历算法的特点就是从小到大访问结点。当遍历访问到根结点时,假设根结点的左侧已经处理好,只需将根结点与上次访问的最近结点(左子树中最大值结点)的指针连接好即可。进而更新当前链表的最后一个结点指针。
2、由于中序遍历过程正好是转换成链表的过程,即可采用递归处理。
《编程之美》——二叉搜索树转换为排序双向链表_第2张图片

代码:

class TreeNode
{
    int val;
    TreeNode left = null;
    TreeNode right = null;
    TreeNode(int val)
    {
        this.val = val;
    }
}

public class Solution 
{
    TreeNode convertNode(TreeNode pNode, TreeNode pLastNodeInList)
    {
        if(pNode == null)
            return;
        TreeNode pCurrent = pNode;

        //递归处理左子树
        if(pCurrent.left != null)
            pLastNodeInList = convertNode(pNode.left, pLastNodeInList);

        //处理当前节点
        //将当前节点的左指针指向已经转换好的链表的最后一个位置
        pCurrent.left = pLastNodeInList;
        //将已经转换好的链表的最后一个节点的右指针指向当前节点
        if(pLastNodeInList != null)
            pLastNodeInList.right = pCurrent;
        //更新已经转换好的链表的最后一个节点
        pLastNodeInList = pCurrent;

        //递归处理右子树
        if(pCurrent.right != null)
            pLastNodeInList = convertNode(pNode.right, pLastNodeInList);
        return pLastNodeInList;
    }

    TreeNode convert(TreeNode pRoot)
    {
        if(pRoot == null)
            return null;

        //处理二叉搜索树
        TreeNode pLastNodeInList = null;
        pLastNodeInList = convertNode(pRoot, pLastNodeInList);

        //找到转换后的链表的头节点
        TreeNode pHead = pLastNodeInList ;
        while(pLastNodeInList != null && pLastNodeInList.left != null)
            pHead = pHead.left;

        //返回头节点
        return pHead;
    }
}

你可能感兴趣的:(《编程之美》——二叉搜索树转换为排序双向链表)