剑指 Offer 36. 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:
在这里插入图片描述
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“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) {
        Node* list = nullptr;
        LDR(root,&list);//此时我们得到的是最后的节点

        Node* head = list;
        while(head && head->left)head=head->left;//寻找首节点

        if(head && list)//首尾链接
        {
            head->left = list;
            list->right = head;
        }

        return head;
    }

    void LDR(Node* pNode,Node** list)//中序遍历链表链接
    {
        if(!pNode)return;

        Node* pCurrent = pNode;
        if(pCurrent->left)LDR(pCurrent->left,list);//寻找左结点

        pCurrent->left = *list;//将根节点指向左侧最小节点
        if(*list)(*list)->right = pCurrent;//双向链表

        *list = pCurrent;//向右改变此时list的值
        if(pCurrent->right)LDR(pCurrent->right,list);
    }
};
©️2020 CSDN 皮肤主题: 点我我会动 设计师:上身试试 返回首页