剑指Offer(第2版)——面试题36:二叉搜索树与双向链表

题目:

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

1.解题思路:
举例说明:
剑指Offer(第2版)——面试题36:二叉搜索树与双向链表_第1张图片

  • 二叉搜索树的特点:左节点值 < 根节点值 < 右节点值,由于转换之后的链表是从小到大排序的,我们可以使用中序遍历来做二叉搜索树的遍历方法;
  • 可以把树分成三个部分:值为10的节点、根节点为6的左子树、根节点为14的右子树。根据排序双向链表的定义,值为10的节点将和它左子树的最大一个节点连接起来,同时它还将和右子树最小的节点连接起来;

剑指Offer(第2版)——面试题36:二叉搜索树与双向链表_第2张图片

  • 按照中序遍历的顺序,当我们遍历到根节点时,它的左子树已经转换成一个排序的好的双向链表了,并且处在链表中最后一个的节点是当前值最大的节点。我们把值为8的节点和根节点连接起来,10就成了最后一个节点,接着我们就去遍历右子树,并把根节点和右子树中最小的节点连接起来。

2.代码:

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution{
public:
    TreeNode* Convert(TreeNode* pRootOfTree){
        //双向链表尾节点初始化
        TreeNode* pLastNodeInList = nullptr;
        //把二叉树转换成双向链表
        ConvertNode(pRootOfTree, &pLastNodeInList);

        //找到双向链表的头节点
        TreeNode* pHeadOfList = pLastNodeInList;
        while(pHeadOfList && pHeadOfList->left){
            pHeadOfList = pHeadOfList->left;
        }

        //返回双向链表的头节点
        return pHeadOfList;
    }
                      //pNode 根节点  //指针的地址
    void ConvertNode(TreeNode* pNode, TreeNode** pLastNodeInList){
        if(!pNode) return;
        TreeNode* pCurrent = pNode;

        //递归左子树。从最左节点开始连起
        if(pCurrent->left) ConvertNode(pCurrent->left, pLastNodeInList);
        //处理当前节点
        //将当前节点的左指针指向已经转换好的双向链表的尾节点
        pCurrent->left = *pLastNodeInList;
        //将已经转换好的双向链表的尾节点的右指针指向当前节点
        if(*pLastNodeInList) (*pLastNodeInList)->right = pCurrent;

        //更新已经转换好的链表的尾节点
        *pLastNodeInList = pCurrent;

        //递归右子树
        if(pCurrent->right) ConvertNode(pCurrent->right, pLastNodeInList);
    }
};

你可能感兴趣的:(剑指Offer(第2版),二叉树,递归)