zoukankan      html  css  js  c++  java
  • 每日一题

    题目信息

    • 时间: 2019-06-29

    • 题目链接:Leetcode

    • tag: 二叉搜索树 中序遍历 递归 深度优先搜索

    • 难易程度:中等

    • 题目描述:

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

    示例:

                  4
                 / 
                2   5
               /    
              1  3  
    

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

    提示

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

    解题思路

    本题难点

    二叉搜索树 转换成一个 “排序的循环双向链表” ,其中包含三个要素:

    • 排序链表: 节点应从小到大排序,因此应使用 中序遍历 “从小到大”访问树的节点;

    • 双向链表: 在构建相邻节点(设前驱节点 pre ,当前节点 cur )关系时,不仅应 pre.right=cur ,也应 cur.left=pre 。

    • 循环链表: 设链表头节点 head 和尾节点 tail ,则应构建 head.left=tail 和 tail.right=head 。

    具体思路

    二叉搜索树的中序遍历为 递增序列

    • 中序遍历

      void dfs(TreeNode root) {
          if(root == null) return;
          dfs(root.left); // 左
          System.out.println(root.val); // 根
          dfs(root.right); // 右
      }
      

    根据以上分析,考虑使用中序遍历访问树的各节点 cur ;并在访问每个节点时构建 cur 和前驱节点 pre 的引用指向;中序遍历完成后,最后构建头节点和尾节点的引用指向即可。

    代码

    /*
    // Definition for a Node.
    class Node {
        public int val;
        public Node left;
        public Node right;
    
        public Node() {}
    
        public Node(int _val) {
            val = _val;
        }
    
        public Node(int _val,Node _left,Node _right) {
            val = _val;
            left = _left;
            right = _right;
        }
    };
    */
    class Solution {
        //pre本来是前序节点,随着中序遍历,最终会成为中序遍历的尾节点
        //head指向中序遍历的头节点
        Node pre,head;
        public Node treeToDoublyList(Node root) {
            if(root == null){
                return null;
            }
            //深度优先搜索二叉搜索树
            dfs(root);
            //将头节点head的左指针指向尾节点pre
            head.left = pre;
            //将尾节点pre的左指针指向头节点head
            pre.right = head;
            //返回结果
            return head;
    
        }
    
        void dfs(Node cur){
          //终止条件: 当节点 cur 为空,代表越过叶节点,直接返回;
            if(cur == null){
                return;
            }
            //递归遍历左子树
            dfs(cur.left);
            //当前节点cur不存在左子树时,此时cur无前驱节点,即前驱节点pre==null,cur为中序遍历的第一个节点
            if(pre == null){
                //将中序遍历的头节点cur赋予双向链表的头节点head
                head = cur;
            }else{
                //当前节点cur存在前置节点pre,将pre的右指针指向cur
                pre.right = cur;
                //当前节点cur存在前驱节点pre,将cur的左指针指向pre,形成双向链表
            		cur.left = pre;
            }
            //将前驱节点pre后移,保存当前节点cur
            pre = cur;
            //递归遍历右子树
            dfs(cur.right); 
        }
    }
    

    复杂度分析:

    • 时间复杂度 O(N) : N 为二叉树的节点数,中序遍历需要访问所有节点。
    • 空间复杂度 O(N) : 最差情况下,即树退化为链表时,递归深度达到 N,系统使用 O(N) 栈空间。

    其他优秀解答

    解题思路

    中序遍历的非递归,使用栈的先进后出特性。

    代码

    public Node treeToDoublyList(Node root) {
            if(root == null){
                return null;
            }
      			//用栈实现
             Stack<Node> stack = new Stack<>();
             Node current = root;
             Node pre = null, head = null;
             while(!stack.isEmpty() || current != null) {
               //内层循环将当前数据入栈
                 while(current != null) {
                     stack.push(current);
                     current = current.left;
                 }
               //出栈并将该元素放入到链表中
                 current = stack.pop();
                 if(pre == null) {//处理头结点
                     head = current;
                 }else {
                     pre.right = current;
                     current.left = pre;
                 }
                pre = current;
               ////将cur指向栈顶元素的右孩子
                current = current.right;
             }
             pre.right = head;
             head.left = pre;
             return head;
        }
    
  • 相关阅读:
    软件设计师考试知识点总结
    HTML和CSS
    JavaScript核心知识点
    操作系统--页面置换算法(缺页数计算)
    中标麒麟系统远程桌面连接
    数据结构 图
    数据结构 二叉树
    MATLAB 大数据剔除坏值
    PTA 邻接表存储图的广度优先遍历(20 分)
    PTA 邻接矩阵存储图的深度优先遍历
  • 原文地址:https://www.cnblogs.com/ID-Wangqiang/p/13218634.html
Copyright © 2011-2022 走看看