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

题目链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/

递归实现1

  1. 二叉搜索树进行中序遍历会得到递增排序的序列;
  2. 将递增排序的序列中每个元素的left和right修改,用两个指针pre和cur完成。pre指的是中序遍历上一个访问的节点,cur表示中序遍历当前访问的节点。那么将pre -> right指向cur,cur -> left指向pre即可;
  3. 处理头和尾,中序遍历完成后,pre指向最后一个节点,头结点如何得到?将第一个访问的节点赋值给head。且第一个节点被访问时,pre的值为NULL,这个节点为head。
    时间复杂度:O(n)
    空间复杂度:O(n)
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;

    Node() {}

    Node(int _val) {
        val = _val;
        left = NULL;
        right = NULL;
    }

    Node(int _val, Node* _left, Node* _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
public:
    Node *pre, *head;
    Node* treeToDoublyList(Node* root) {
        if(!root) return root;
        dfs(root);
        head -> left = pre;
        pre-> right = head;
        return head;
    }
    void dfs(Node *cur)
    {
        if(!cur) return ;
        dfs(cur-> left);
        if(!pre) head = cur;
        else
        {
            pre -> right = cur;
            cur-> left = pre;
        }
        pre = cur;
        dfs(cur-> right);
    }

};

递归实现2

用flag指示返回最左/最右节点,递归后序遍历操作

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;

    Node() {}

    Node(int _val) {
        val = _val;
        left = NULL;
        right = NULL;
    }

    Node(int _val, Node* _left, Node* _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
public:
    Node* treeToDoublyList(Node* root) {
        root = treeToDoublyList(root, 0);
        
        if(!root) return NULL;
        Node* p = root;
        while(p -> right) p = p -> right;
        p -> right = root;
        root -> left = p;
        return root;
    }
    Node* treeToDoublyList(Node *root, int flag)
    {
        if(root == NULL) return NULL;
        Node *left_ = treeToDoublyList(root -> left, 1);
        Node *right_ = treeToDoublyList(root -> right, 0);

        root -> left = left_;
        root -> right = right_;

        if(left_) left_ -> right = root;
        if(right_) right_ -> left = root;
        Node *p = root;
        if(!flag) while(p -> left) p = p -> left;
        else while(p -> right) p = p -> right;
        return p;
    }

};
posted @ 2020-04-29 23:25  NaughtyCoder  阅读(101)  评论(0)    收藏  举报