zoukankan      html  css  js  c++  java
  • 面试题36:二叉搜索树与双向链表(C++)

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

    题目描述:

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

    题目示例:

    二叉搜索树转为双向链表

    我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

     

    特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。 

    解题思路

    思路1:分析题目可知,首先,循环链表顺序是单调递增,所以,观察二叉搜索树的三种遍历方式,发现二叉搜索树的中序遍历(左子树->根节点->右子树)满足条件,即从小到大遍历树的节点,然后,考虑循环链表的指向问题,这里我们使用双指针pre和head,其中pre表示前驱节点,head表示头节点,cur表示当前节点,tail表示尾节点,则双向链表的指向问题可以表示为pre->right=cur;cur->left=pre;这样我们就构造好了双向链表,最后就是循环链表的问题了,将尾节点的左指针指向头节点,头节点的右指针指向尾节点,即head->left=tail;tail->right=head。

    思路2:类似于思路1,不过这里使用数组arr存储中序遍历的每个节点,这样arr数组中元素顺序单调递增,然后利用一层循环使得相邻元素连接构成双向链表,最后改变首尾元素的指向,即可得到循环双向链表。

    程序源码

    中序遍历+递归

    /*
    // 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 = nullptr, *head = nullptr, *tail = nullptr;
        Node* treeToDoublyList(Node* root) {
            if(root == nullptr) return nullptr;
             inorder(root);
             //连接首尾节点
             head->left = tail;
             tail->right = head;
             return head;
        }
        void inorder(Node* cur)
        {
            if(cur == nullptr) return; //递归出口
            inorder(cur->left); //遍历左子树
            if(pre != nullptr) pre->right = cur;
            else head = cur;
            cur->left = pre;
            pre = cur;
            tail = cur;
            inorder(cur->right); //遍历右子树
        }
    };

    数组

    /*
    // 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:
        vector<Node*> arr;
        Node* treeToDoublyList(Node* root) {
            if(root == nullptr) return nullptr;
             inorder(root);
             for(int i = 0; i < arr.size() - 1; i++)
             {
                 arr[i]->right = arr[i + 1];
                 arr[i + 1]->left = arr[i];
             }
             arr[arr.size() - 1]->right = arr[0];
             arr[0]->left = arr[arr.size() - 1];
             return arr[0];
        }
        void inorder(Node* cur)
        {
            if(cur == nullptr) return; //递归出口
            inorder(cur->left); //遍历左子树
            arr.push_back(cur); //装入当前节点
            inorder(cur->right); //遍历右子树
        }
    };

    参考文章

    https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/solution/mian-shi-ti-36-er-cha-sou-suo-shu-yu-shuang-xian-5/

    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    [转载]写作经验谈--如何写一本书?
    决定写一本书
    c中自定义函数通过sizeof来输出数组的长度为何不正确?【原创】
    [转]关于PHP的漏洞以及如何防止PHP漏洞?
    [转]PHP安全之防止你的源代码或重要配置信息暴露在外
    PHPUnit 单元测试框架(鸡肋)
    [转]避免PHP-FPM内存泄漏导致内存耗尽
    [转]PHP ffmpeg截取视频指定帧为图片,获取rotation信息并旋转
    ThinkPHP 缓存 以及Zend OPCache提升PHP性能
    简单测漏 语句
  • 原文地址:https://www.cnblogs.com/wzw0625/p/12796134.html
Copyright © 2011-2022 走看看