【剑指 offer】二叉搜索树与双向链表。

1、题目描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。

要求不能创建任何新的结点,只能调整树中结点指针的指向。

注意

  • 需要返回双向链表最左侧的节点。

例如,输入下图中左边的二叉搜索树,则输出右边的排序双向链表。

2、问题描述:

  • BST转化成排序的双向链表,所以就是BST的中序遍历序列。

3、问题关键:

  • 中序遍历是有序的,左中右。
  • 将左子树的右指针指向自己。右子树的左指针指向自己。

4、C++代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* convert(TreeNode* root) {
        if (!root) return root;
        auto sides = dfs(root);//递归
        return sides.first;
    }
    pair dfs(TreeNode* root) {
        if (!root->left && !root->right) return {root, root};//出口条件,到达叶结点了。
        if (root->left && root->right) {//如果有左右子树,那么分别递归左右子树。
            auto lside = dfs(root->left), rside = dfs(root->right);
            lside.second->right = root, root->left = lside.second;//左子树的右指针指向root,root的左指针指向左边的最后一个。
            rside.first->left = root, root->right = rside.first;//root的右指针指向右边第一个,右边的第一个的左指针指向root。
            return {lside.first, rside.second};//返回左子树的最左边的,和右子树最右边的。
        }
        if(root->left) {//如果只有左子树,那么只有递归左边的就可以了。是上面的一种情况。
            auto lside = dfs(root->left);
            lside.second->right = root, root->left = lside.second;
            return {lside.first, root};
        }
        if (root->right) {//只有右子树,同只有左。
            auto rside = dfs(root->right);
            rside.first->left = root, root->right = rside.first;
            return {root,  rside.second};
        }
    }
};

你可能感兴趣的:(【剑指 offer】二叉搜索树与双向链表。)