1. 程式人生 > 實用技巧 >【LeetCode-樹】二叉搜尋樹與雙向連結串列

【LeetCode-樹】二叉搜尋樹與雙向連結串列

題目描述

輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的迴圈雙向連結串列。要求不能建立任何新的節點,只能調整樹中節點指標的指向。
為了讓您更好地理解問題,以下面的二叉搜尋樹為例:

我們希望將這個二叉搜尋樹轉化為雙向迴圈連結串列。連結串列中的每個節點都有一個前驅和後繼指標。對於雙向迴圈連結串列,第一個節點的前驅是最後一個節點,最後一個節點的後繼是第一個節點。
下圖展示了上面的二叉搜尋樹轉化成的連結串列。“head” 表示指向連結串列中有最小元素的節點。

特別地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指標需要指向前驅,樹中節點的右指標需要指向後繼。還需要返回連結串列中的第一個節點的指標。
題目連結:

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

思路

二叉搜尋樹的中序遍歷序列是一個升序序列,所以可以中序遍歷求解該題。因為是要轉成雙向連結串列,所以要儲存當前節點 cur 的前驅節點 pre,在遍歷過程中設定 cur->left = pre, pre->right = cur。

還有一個問題就是首尾要相連。當遍歷結束時,pre 為連結串列的最後一個節點,所以我們再設定一個指標 head 表示頭節點,在中序遍歷開始的時候,pre 為空,這時我們將當前節點 cur 賦值給 head,這樣我們就得到了連結串列的首尾節點,最後令 head->left = pre,pre->right = head 即可。

程式碼如下:

/*
// 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) {
        if(root==nullptr) return root;
        
        dfs(root);
        head->left = pre;
        pre->right = head;
        return head;
    }

    void dfs(Node* cur){
        if(cur==nullptr) return;

        dfs(cur->left);
        if(pre==nullptr) head = cur;
        else pre->right = cur;
        cur->left = pre;
        pre = cur;
        dfs(cur->right);
    }

private:
    Node* pre;
    Node* head;
};

參考

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