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

2021-05-23  本文已影响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};
        }
    }
};
上一篇下一篇

猜你喜欢

热点阅读