版权声明:

本文由Faye_Zuo发布于http://www.cnblogs.com/zuofeiyi/, 本文可以被全部的转载或者部分使用,但请注明出处.

上周学习了数组和链表,有点基础了解以后,这周初步探索了一下深度优先搜索。对于文科生的我来说,这个名词听起来有点可怕。于是我通过leetcode上的一个难度为medium的题目来逐渐认识这个概念的。这道题目是Validate Binary Search Tree(题号为98)。下面我将通过这道题作为引子,整理一下上周学习到的东西。

一、树

这道题目是让我们判断这棵树是否为有效二叉查找树。但是我连树是什么都是一脸茫然。后来通过学习youtube上的视频,对他有逐步了解。树的概念容易理解,现在主要看看它的存储结构(其实我也不知道了解到存储结构有什么用)

树的存储结构如下:

(1)双亲表示法
以一段连续空间来存储树的结点,在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。这样,每个结点除了知道自己是谁以外,还知道自己双亲的位置。
(2)孩子表示法:用多重链表来表示
(3)双亲孩子表示法:上述两种的结合

二、二叉树(Binary Tree)

有了对树的认识以后,二叉树的基本概念就更加容易理解了。

1.概念:每个节点最多有两个节点的结构树,通常子树被称为左子树和右子树。
 
2.二叉树的建立(非常重要)
 
public static void main(String[] args) {
/* Making a tree like :
0
/ \
1 2
/
3
*/ TreeNode root = new TreeNode(0);
root.left = new TreeNode(1);
root.right = new TreeNode(2);
root.left.left = new TreeNode(3);
3.二叉树的遍历
 private static class TreeNode {
    public TreeNode(int x) {    //红色标记部分不是成员函数,是构造函数,主要用来初始化的。所以也不需要有返回值类型。
      this.x = x;
    }
 
    public int x;
    public TreeNode left;//left和right就是变量
    public TreeNode right;
  }
 
  /* pre-order, 先序遍历 */
  private static void traverseTreePreOrder(TreeNode node) {
    if (node != null) {
      System.out.println(node.x);
      traverseTreePreOrder(node.left);
      traverseTreePreOrder(node.right);
    }
  }
 
  /* in-order, 中序遍历 */
  private static void traverseTreeInOrder(TreeNode node) {
    if (node != null) {
      traverseTreeInOrder(node.left);
      System.out.println(node.x);
      traverseTreeInOrder(node.right);
    }
  }
 
  /* post-order, 后序遍历 */
  private static void traverseTreePostOrder(TreeNode node) {
    if (node != null) {
      traverseTreePostOrder(node.left);
      traverseTreePostOrder(node.right);
      System.out.println(node.x);
    }
  } 
 
三、然后我就可以开始看看这道leetcode上的题目了

Validate Binary Search Tree(98)
Given a binary tree, determine if it is a valid binary search tree(BST).
Assume a BST is defined as follows:
(1)The left subtree of a node contains only nodes with keys less than the node’s key.
(2)The right subtree of a node contains only nodes with keys greater than the node’s key.
(3)Both the left and right subtrees must also be binary search trees. 
 
完全不会做啊,于是只有看答案,发现这道题主要要用到递归,思路如下:
 

1.所有的在左边的值必然小于root,所有在右边的值必然大于root。
2.我们要看的是每个节点是不是都满足BST。
3.我们要将这个上限和下限代入递归中。 
 
完整解答的程序:

public class BinarySearchTree {

public static void main(String[] args) {
    TreeNode root=new TreeNode(6);
    root.left=new TreeNode(1);
    root.right=new TreeNode(7);
    root.left.left=new TreeNode(4);
   

    Solution A=new Solution();
    System.out.println(A.isValidBST(root));//为什么new了新对象,还需要将下面的方法改为静态?原因就是看下面的方法是不                        
                                                            //是访问到了对象中特有数据。如果访问到了,加static。
 
  }
  public static class TreeNode{
     int val;
     TreeNode left;
     TreeNode right;
     TreeNode(int x){
      val=x;
    }
  }
 
  public static class Solution{
    public  boolean isValidBST(TreeNode root){
      return isValidBST(root,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY);
    }
   
    public boolean isValidBST(TreeNode p,double min, double max){
      if(p==null)
        return true;
     
      if(p.val<=min||p.val>=max)
        return false;
 
      return isValidBST(p.left,min,p.val)&&isValidBST(p.right,p.val,max);
    }
   
   
  }
  }
 
 
在以上的程序中,我发现我有好多知识点都需要再学习,再补充。整理如下:

1.一些固定需要记住的class
Double.NEGATIVE_INFINITY 表示负数无穷小
Double.POSITIVE_INFINITY 表示正数无穷大
 
2.需要死记的一个算法(写得真的太好了)

public  boolean isValidBST(TreeNode root){
      return isValidBST(root,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY);
    }
   
    public boolean isValidBST(TreeNode p,double min, double max){
      if(p==null)
        return true;
     
      if(p.val<=min||p.val>=max)
        return false;
 
      return isValidBST(p.left,min,p.val)&&isValidBST(p.right,p.val,max);
    }
 
 

3.java中关于静态知识点的讲解
(1)成员变量又叫实例变量,但是静态变量又叫类变量,它是类能直接访问的变量。
(2)成员变量和静态变量的区别:
生命周期:成员变量随着对象的创建而存在,随着对象的回收而释放。静态变量随着类的存在而存在,随着类的消失而消失。
调用方式:成员变量只能被对象调用。静态对象可以被类名调用,也可以被对象调用。
数据存储位置不同:成员变量存储在堆内存的对象中,静态变量存储在方法区中。
(3)static在使用过程中应该注意的细节:
   a.静态方法只能访问静态成员。注意一个常见的报错:无法从静态方法中调用非静态。原因是静态变量会先加载,加载的时候非静态变量中还没有对象。
   b.静态方法中不可以使用this或者super关键字。
   c.主函数一定是静态的。
 (4) 什么时候使用static关键字
静态变量:当对象中所具备的成员变量的值是相同的,这时成员可以被静态修饰。
静态函数:关注一点! 该函数的功能是否访问到对象中的特有数据(特有数据:对象的值)。
 
 4. 递归

(1).递归的最基本思想:自己调用自己
(2).递归必须要有一个出口,即告诉别人什么时候可以不用调用了。否则这个函数会进入一个死循环,直到栈溢出。说白了就是一个if else
(3).递归的特点:耗时间、耗空间(一层一层的调用,再一层一层的返回) 
 
5. 补充面向对象的基本知识

(1)什么是方法:方法就是函数(method)
 
(2)方法的重载:
其实就是同一方法名下,通过参数的不同,可以实现函数的不同功能。
public void tell(int i,int j){}
public void tell(string k){} 
 
本周学习的东西就大致整理分享到这里,下周准备再多练习几道leetcode关于树的题目。希望可以对树这种数据结构有更加深入的理解!
加油!
 

初涉深度优先搜索--Java学习笔记(二)的更多相关文章

  1. 平面上的地图搜索--Java学习笔记(四)

    版权声明: 本文由Faye_Zuo发布于http://www.cnblogs.com/zuofeiyi/, 本文可以被全部的转载或者部分使用,但请注明出处. 这一个月以来,都在学习平面上的地图搜索,主 ...

  2. 深度优先搜索 DFS 学习笔记

    深度优先搜索 学习笔记 引入 深度优先搜索 DFS 是图论中最基础,最重要的算法之一.DFS 是一种盲目搜寻法,也就是在每个点 \(u\) 上,任选一条边 DFS,直到回溯到 \(u\) 时才选择别的 ...

  3. Java学习笔记二十九:一个Java面向对象的小练习

    一个Java面向对象的小练习 一:项目需求与解决思路: 学习了这么长时间的面向对象,我们只是对面向对象有了一个简单的认识,我们现在来做一个小练习,这个例子可以使大家更好的掌握面向对象的特性: 1.人类 ...

  4. 数组排序、递归——(Java学习笔记二)

    升序:      选择排序:         选定一个元素,一次和后面的元素相比较,如果选定的元素大雨后面的比较元素,就交换位置         先出现最小值,最后出现最大值. public stat ...

  5. Java学习笔记二---设置环境变量JAVA_HOME,CLASSPATH,PATH

    1.环境变量包括: JAVA_HOME,CLASSPATH,PATH 2.设置环境变量的目的: 路径搜索,方便查找到jdk的安装路径.方便搜索用到的类文件.方便搜索用到的可执行文件如java,java ...

  6. Java学习笔记二:数据类型II

    GitHub代码练习地址:https://github.com/Neo-ML/JavaPractice/blob/master/Intpractice3.java 一  Java中的数据类型 Java ...

  7. Java学习笔记二十八:Java中的接口

    Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...

  8. Java学习笔记二十七:Java中的抽象类

    Java中的抽象类 一:Java抽象类: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就 ...

  9. Java学习笔记二十五:Java面向对象的三大特性之多态

    Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...

随机推荐

  1. ftp org.apache.commons.net.ftp.FTPClient 判断文件是否存在

    String path = "/SJPT/ONPUT/HMD_TEST/" ; FtpTool.getFTPClient().changeWorkingDirectory(path ...

  2. JS根据经纬度获取地址信息

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  3. 数据分析师的福音——VS 2017带来一体化的数据分析开发环境

    (此文章同时发表在本人微信公众号“dotNET开发经验谈”,欢迎右边二维码来关注.) 题记:在上个月的Connect() 2016大会上,微软宣布了VS 2017 RC的发布,其中为数据分析师带来了一 ...

  4. 关于Knockout的开始

    最近看了汤姆大叔的Knockout,感到MVVM的神奇,也许这就是以后编程的方式,最直观的感觉就是层次更分明了. 绑定,模型转换,监控,在我来说,这算是编程上的一个转变,在以后我做不定期的更新一些MV ...

  5. 初识Python-Python介绍

    Python介绍 在了解了计算机以及操作系统的发展历程之后,又接触到了一门新的语音——Python,迈出了学习编程的第一步. 一.Python简介: Python(英国发音:/ˈpaɪθən/ 美国发 ...

  6. FZU 2137 奇异字符串 后缀树组+RMQ

    题目连接:http://acm.fzu.edu.cn/problem.php?pid=2137 题解: 枚举x位置,向左右延伸计算答案 如何计算答案:对字符串建立SA,那么对于想双延伸的长度L,假如有 ...

  7. (UWP开发)更为合理的一种ListView下拉刷新(PullToRefresh)实现方法

    最近在做的一个项目需要用到下拉刷新,但是参考了现在网络上比较普遍的方法,觉得都不太好,因为要在外部套上一个SrollViewer,容易出现滚动错误.于是刚开始的时候就把思路定到了ListView内部的 ...

  8. DOM事件

    在慕课网上学习了DOM事件探秘课程,特此整理了一下笔记. 慕课网DOM事件探秘课程地址:http://www.imooc.com/learn/138 事件 是文档或浏览器窗口中发生的特定的交互瞬间.[ ...

  9. python 小程序 比较目录间的差异

    比较目录间的差异: I 只按照名称做了比较,如果目录的文件名称相同,但是内容不同脚本认为为相同文件 II 针对目录下面的目录没有循环比较,只是比较了目录的名称 import sys, os def d ...

  10. 如何用hypermesh生成包含interface的流体网格

    在计算气动声学的时候,有些情况是需要我们提取流体计算的结果作为声学分析的边界条件,但是,有些流体网格因为物理模型的问题需要我们设定interface,恰恰你是机械,对流体了解一点,又不想花费太多时间来 ...