zoukankan      html  css  js  c++  java
  • 剑指Offer对答如流系列

    面试题36:二叉搜索树与双向链表

    题目描述

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

    二叉树节点的定义如下:

        public class Node {
            int val = 0;
            Node left = null;
            Node right = null;
    
            public Node(int val) {
                this.val = val;
            }
        }
    

    比如,输入下图的二叉搜索树,则输出转换之后的排序双向链表。
    在这里插入图片描述

    在这里插入图片描述

    问题分析

    二叉搜索树中序遍历的结果是排序的。

    问题的解答一下子就明朗了,中序遍历先处理左子树,再处理根结点,之后处理右子树。在处理时,我们构建双向链表。

    整个思路的大致流程:假设左子树处理完了,就要处理根结点,而根结点必须知道左子树的最大结点,所以要用函数返回值记录下来;之后处理右子树,右子树的最小结点(也用中序遍历得到)要和根结点链接。

    在这里插入图片描述
    在这里插入图片描述

    问题解答

    (1)递归写法

        public Node Convert(Node root) {
            
            if (root == null) {
                return root;
            }
            
            // 处理左子树,获得左子树链表的头结点
            Node left = Convert(root.left);
            Node p = left;
            if (left != null) {
                // 找到左子树链表的末尾结点
                while (p.right != null) {
                    p = p.right;
                }
                // 连接结点 
                p.right = root;
                root.left = p;
            }
            // 处理右子树,获得右子树链表的头结点
            Node right = Convert(root.right);
            // 连接结点
            if (right != null) {
                root.right = right;
                right.left = root;
            }
            return left == null ? root : left;
        }
    

    (2)非递归写法

    利用非递归中序遍历来连接结点

     public Node Convert(Node root) {
            Node head = null;
            Node pre = null;
            LinkedList<Node> stack = new LinkedList<>();
            while (root != null || !stack.isEmpty()) {
                // 把root当作引用使用
                while (root != null) {
                    stack.push(root);
                    root = root.left;
                }
                Node node = stack.pop();
                if (head == null) {
                    head = node;
                    pre = node;
                } else {
                    node.left = pre;
                    pre.right = node;
                    pre = node; // 别漏写了
                }
                root = node.right;
            }
            return head;
        }
    
  • 相关阅读:
    SQL Server 2005 全文搜索包括改进和更新的干扰词文件FROM MS KB
    服务器内存选项From MS
    跳过事务复制中的错误
    WP7基础补充
    TaoBaoAPI简介3
    登录功能代码
    TaoBaoApI简介1
    TaoBaoAPI简介2
    WP7基础学习第十三讲
    WP7基础学习第十四讲
  • 原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12246414.html
Copyright © 2011-2022 走看看