美文网首页
剑指offer 37- 二叉搜索树与双向链表

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

作者: 顾子豪 | 来源:发表于2021-05-23 12:26 被阅读0次

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

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

    注意

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

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


    分析:

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

    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<TreeNode*, TreeNode*> 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};
            }
        }
    };
    

    相关文章

      网友评论

          本文标题:剑指offer 37- 二叉搜索树与双向链表

          本文链接:https://www.haomeiwen.com/subject/lgzljltx.html