本文是在复习数据结构过程中的记录,主要内容是记录了自己遇到的问题以及怎么解决。当然,对他人可能没什么帮助。
文章目录
树的理论知识点
- 二叉查找树是什么意思?
- 父节点的值比左节点大,比右节点小
- 完全二叉树
- 在用数组存储二叉树结构时,数组除了0位置外,别的位置都被填满了,没有空隙(数组后面还是可以有空隙的)
实现二叉排序树的基本操作
- 树需要初始化吗?怎么初始化?——不需要
- 实现二叉树跟实现二叉树结点要分开
- 二叉树和结点的类能不能写在一个文件中,怎么写?
- 可以,在树的定义内部构造结点类即可
- 构造器没有返回值,不要乱写
- 结点Node的构造器中,Val值应该初始化为什么呢?——传一个值,该值就是Val的值
- 在写类的时候,需要一个无参构造器(没有参数、没有实现的构造器是需要的,因为如果是继承父类的子类,那它没有,java编译器会给他父类的构造器,这样的话经常会出错)
- 二叉树和结点的类能不能写在一个文件中,怎么写?
- 树的新增结点应该怎么递归实现?
- 新增结点时,应该是给结点新增一个值,而不是给一个树新增结点
- 找到对的位置了,应该怎么插入?——如果当前Node为null,直接构造一个结点并返回
- 插入的递归方法中,参数应该是:当前指向的Node以及新的值(int),是把新的值插到当前的Node中去(不一定是这个Node自己的Val域,可以是它的左子树或者右子树)
- 如果碰到相同的值,二叉树该如何取舍?——不要
- root需要是静态的吗?——不用
- 删除结点(删除后需要保持大小顺序)
- assertTrue()有什么用?——如果传的参数为True,那就不报错;assertFalse是相反
- 使用时需要引入:
import static org.junit.Assert.*;
- 使用时需要引入:
- 递归删除的参数和返回值——传入结点、要删除的值,返回一个结点
- 找到了结点,怎么进行删除?——教程写的是返回null,最后返回给root,那这样岂不是把整个树都置空了吗?
- 并不会,你这个null不是一路返回到root的,而是上一层的子结点的null。换句话说就是,这个null值不会传播,也不是整体。
- 在判断当前结点是否就是要删除的结点的时候,不能用if else,因为这是递归函数
- 在删除子树时(有1个子树的情况),直接返回子树。这是因为当前的函数是要返回到上一层函数中的,上一层函数会将你删除好了的所有枝节再打包返回给root(这也太巧妙了)。所以这个删除函数才会没有free函数之类的操作。
- 要删除的结点有两个结点:
- 将右子树中最小的结点替代原来的结点,怎么实现呢?——获取值、删除结点
- 在找到要删除的结点时,
- 遍历
- 广度优先遍历怎么做?
- 用队列实现:队列的实现是用LinkedList<>(),即
Queue<Node> nodes = new LinkedList<>();
- 将根加入到队列中,while队列不为空,就出队、打印,然后把左右子树加入队列。
- 用队列实现:队列的实现是用LinkedList<>(),即
- 广度优先遍历怎么做?
- assertTrue()有什么用?——如果传的参数为True,那就不报错;assertFalse是相反
源码
package com.company;
import org.junit.Test;
import java.util.LinkedList;
import java.util.Queue;
import static org.junit.Assert.*;
public class BinaryTree {
Node root; //根结点
//结点的定义
public static class Node {
private int val;
Node left;
Node right;
public Node(int val)
{
this.val = val;
this.left = null;
this.right = null;
}
public Node() //空构造器
{
/*val = 0;
left = null;
right = null;*/
}
public int getVal() {
return val;
}
public void setVal(