zoukankan      html  css  js  c++  java
  • 二叉搜索树与双向链表

    来源: 牛客网

    题目描述

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

    插图来自《剑指offer》

    可见,二叉搜索树的中序遍历即是一个有序数组。然后动手写代码,但是让人苦恼的是牛客网给出的函数定义(我是javaer):

    /**
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
    
        public TreeNode(int val) {
            this.val = val;
    
        }
    
    }
    */
    public class Solution {
        public TreeNode Convert(TreeNode pRootOfTree) {
            
        }
    }

    按照一贯做法,此题要返回排序双向链表的头节点。

    加上中序遍历的函数后:

    public class Solution {
        public TreeNode Convert(TreeNode pRootOfTree) {
            if(pRootOfTree==null) return null;
            inOrder(pRootOfTree);
            ……
            ……
            }
        }
    
        public void inOrder(TreeNode node){
            if(node!=null){
                inOrder(node.left);
                print(node); // 访问此节点
                inOrder(node.right);
            } 
        }
    }

    inOrder 函数没有返回值,因此必须在Solution 类中定义一个域来存储中序遍历序列。之前没有这样写过,不知道牛客网的测试程序是什么情况。查看《剑指offer》中,是以引用的形式将Convert函数中的一个TreeNode结构体指针传递给ConvertNode函数(相当于上面的inOrder函数),这样在ConvertNode函数中才能修改Convert函数中变量的内容。java中没有这种写法。

    我尝试在Solution类中定义一个ArratList<TreeNode>存储中序遍历序列,然后牛客网接受了这种写法。AC代码如下:

    解释一下题目中“要求不能创建任何新的结点”这句话,意思是用new 关键字即调用了TreeNode类构造函数,这才叫创建了一个新的节点。

    下面代码中的ArrayList<TreeNode>只是一个容器,用来辅助存储这些树节点,然后在遍历的时候调整节点的左右指针,整个过程中没有创建新节点。因此是符合题目要求的。

     1 import java.util.*;
     2 /**
     3 public class TreeNode {
     4     int val = 0;
     5     TreeNode left = null;
     6     TreeNode right = null;
     7 
     8     public TreeNode(int val) {
     9         this.val = val;
    10 
    11     }
    12 
    13 }
    14 */
    15 public class Solution {
    16     ArrayList<TreeNode> l = new ArrayList<TreeNode>();
    17     public TreeNode Convert(TreeNode pRootOfTree) {
    18         if(pRootOfTree==null) return null;
    19         inOrder(pRootOfTree);
    20         if(l.size()==1) return l.get(0);
    21         else {
    22             l.get(0).right=l.get(1);
    23             for(int i=1; i<l.size()-1; ++i){
    24                 l.get(i).left=l.get(i-1);
    25                 l.get(i).right=l.get(i+1);
    26             }
    27 
    28             l.get(l.size()-1).left=l.get(l.size()-2);
    29             return l.get(0);
    30         }
    31     }
    32 
    33     public void inOrder(TreeNode node){
    34         if(node!=null){
    35             inOrder(node.left);
    36             l.add(node);
    37             inOrder(node.right);
    38         } 
    39     }
    40 }

    cd

  • 相关阅读:
    diary and html 文本颜色编辑,行距和其它编辑总汇
    bash coding to changeNames
    virtualbox ubuntu 网络连接 以及 连接 secureCRT
    linux 学习6 软件包安装
    linux 学习8 权限管理
    vim 使用2 转载 为了打开方便
    ubuntu
    linux 学习15 16 启动管理,备份和恢复
    linux 学习 14 日志管理
    linux 学习 13 系统管理
  • 原文地址:https://www.cnblogs.com/duanguyuan/p/5705923.html
Copyright © 2011-2022 走看看