剑指offer 37- 二叉搜索树与双向链表

时间:2021-7-4 作者:qvyue

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

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

注意

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

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

剑指offer 37- 二叉搜索树与双向链表

分析:

算法一:对中序递归遍历的改进

1.定义一个pre指针用来保存中序遍历的前一个结点。

注:

  • 中序遍历,遍历顺序就是双线链表的建立顺序;

2.递归遍历左子树
3.修改left指针和right指针(令当前结点left指针指向pre,pre的right指针指向当前结点),移动pre指针到当前结点
4.递归遍历右子树

5.最后需要一直向左找到双向链表的头结点。

/**
 * 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* pre = nullptr;//这里没有违背题目要求,因为并没有开辟新的空间指向新的Node
    TreeNode* head;
    TreeNode* convert(TreeNode* root) {
        dfs(root);
        // while(root && root->left) root = root->left;
        return head;
    }
    
    void dfs(TreeNode* root) {
        if(!root) return;
        dfs(root->left);
        
        root->left = pre;//修改left指针
        if(pre) pre->right = root;//修改right指针
        else head = root;
        pre = root;//移动pre指针到当前结点
        
        dfs(root->right);
    }
};

算法二:

/**
 * 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;
            rside.first->left = root, root->right = rside.first;
            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};
        }
    }
};
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。