week07_day03_Tree

2023-12-03 23:58
文章标签 tree day03 week07

本文主要是介绍week07_day03_Tree,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

二叉查找树(可以根据这棵树查找结点):
又叫二叉排序树(中序遍历的结果是有序的)。要求树中的结点可以按照某个规则进行比较。

左子树中所有结点的key比根结点的key小,并且左子树也是二叉搜索树。
右子树中所有结点的key比根结点的key大,并且右子树也是二叉搜索树。

  • Q1: BST 能存储null吗?为什么?
    不能,BST要求元素能进行比较

  • Q2: BST 能存储key相同的对象吗?为什么?如果不能,可以改进吗?
    按照BST的定义是不能存储key相同的对象的。
    如何改进?
    #1:可以在结点添加一个count属性。
    但是我需要存储的是Student对象,这个Student对象包含一个学生的所有信息。而不是有几个15岁的同学
    #2: 拉链法, 在结点添加一个next指针域。
    next执行和key相同的下一个元素。可以看成这个二叉排序树存储的是value值为key的链表开发中大多用拉链法
    #3:修改BST的定义: 左子树 <= (右子树 >=)

实现:
查找:先取根结点,如果它等于我们要查找的数就返回;如果查找的数据比根节点小,就在左子树中递归查找;如果要查找的数据比根结点大,那么就在右子树中递归查找。

插入:如果要插入的数据比结点大,并且结点的右子树为空,就将新数据直接插到右孩子的位置;如果不为空,就再递归遍历右子树,查找插入位置。同理,如果要插入的数据比结点小,并且结点的左子树为空,就将新数据插入到左孩子的位置;如果不为空,就再递归遍历左子树,查找插入位置。

·························································································································································································

package com.cskaoyan.tree;import sun.reflect.generics.tree.Tree;import java.util.ArrayList;
import java.util.List;/*** @author shihao* @create 2020-05-20 10:33* <p>* API:* 增:boolean add(E e) 添加成功返回true,否则返回false(二叉排序树中有和e相同的值)* 删:boolean remove(E e) 删除成功返回true,否则返回false(二叉排序树中无和e相同的值)* void clear();  清空树中所有元素* 查:boolean contains(E e)* E min()* E max()  求最大值和最小值* 遍历:List<E> preOrder();* List<E> inOrder();* List<E> postOrder();* List<E> levelOrder();* 建树:静态方法,因为建树操作不依赖于BinarySearchTree对象而存在* static <T> BinarySearchTree buildTree(List<T> preOrder,List<T> inOrder)* 获取属性:* boolean isEmpty()  判空* int size()   结点个数* int height()  树的高度(二叉排序树的性能是依赖于二叉排序树的高度的)*/
//我们希望BinarySearchTree结点可以进行比较,在java中除了基本数据类型外,
// 要想实现比较,得实现Comparable接口,而Comparable接口本身就是泛型接口,
// 所以得Comparable<E>,如果不写<E>的话,我们认为它可以对任意元素(Object)进行比较的
//public class BinarySearchTree<E extends Comparable<E>>
//第一个<E>定义泛型,第二个<E>使用泛型。但这样的话只能对E类型的元素进行比较
//但这样写还不够好
// public class BinarySearchTree<E extends Comparable<? super E>>
// Comparable<? super E>表示能对E的父类进行比较
// 那能对E的父类进行比较,就一定能对E进行比较
public class BinarySearchTree<E extends Comparable<E>> {//属性private TreeNode root;private int size;private class TreeNode {TreeNode left;E value;TreeNode right;public TreeNode(E value) {this.value = value;}public TreeNode(TreeNode left, E value, TreeNode right) {this.left = left;this.value = value;this.right = right;}}//构造方法//刚开始创建一颗空树,size = 0, root = null就可以不用写构造方法//方法/*** 在BST中插入一个元素** @param key 待插入的元素* @return 如果插入成功返回true,失败返回false*/
/*public boolean add(E key) {if (key == null) {throw new IllegalArgumentException("key cannot be null");}//处理空树情况if (root == null) {root = new TreeNode(key);size++;return true;}TreeNode p = null;TreeNode x = root;int cmp;do {cmp = key.compareTo(x.value);if (cmp < 0) {//往左走p = x;x = x.left;} else if (cmp > 0) {//往右走p = x;x = x.right;} else return false;} while (x != null);//插入结点TreeNode node = new TreeNode(key);if (cmp > 0) p.right = node;else p.left = node;size++;return true;}
*///add方法的递归实现public boolean add(E key) {if (key == null) {throw new IllegalArgumentException("key cannot be null");}int oldSize = size;// 在root这棵树中插入key,并把新的根节点赋值给root//不能直接调用add(E key)这个方法,这个方法不能把问题规模给减小// 也就是说,我只知道要插入key,不知道在哪个位置插入keyroot = add(root, key);return oldSize < size;}private TreeNode add(TreeNode node, E key) {//边界条件//node == null 说明这就是要插入的位置if (node == null) {size++;return new TreeNode(key);}int cmp = key.compareTo(node.value);if (cmp < 0) {//在左子树中插入key,并链接到node.leftnode.left = add(node.left,key);} else if(cmp>0){//在右子树中插入key,并链接到node.rightnode.right = add(node.right,key);}//如果触cmp == 0,就什么也不做return node;}/*** 获取BST中元素的个数** @return 元素的个数*/public int size() {return size;}/*** BST先序遍历** @return 先序遍历列表*/public List<E> preOrder() {List<E> list = new ArrayList<>();//遍历BST,并把元素放入list中preOrder(root, list);return list;}private void preOrder(TreeNode node, List<E> list) {//边界条件 node == null表示遍历到了叶子结点 直接返回即可if (node == null) return;//遍历根节点list.add(node.value);//遍历左子树preOrder(node.left, list);//遍历右子树preOrder(node.right, list);}/*** BST中序遍历** @return 中序遍历列表*/public List<E> inOrder() {ArrayList<E> list = new ArrayList<>();//遍历BST,并把元素放入list中inOrder(root, list);return list;}private void inOrder(TreeNode node, ArrayList<E> list) {if (node == null) return;//遍历左子树inOrder(node.left, list);//遍历根节点list.add(node.value);//遍历右子树inOrder(node.right, list);}/*** BST后序遍历** @return 后序遍历列表*/public List<E> postOrder() {ArrayList<E> list = new ArrayList<>();postOrder(root, list);return list;}private void postOrder(TreeNode node, ArrayList<E> list) {//边界条件if (node == null) return;//遍历左子树postOrder(node.left, list);//遍历右子树postOrder(node.right, list);//遍历根节点list.add(node.value);}public static void main(String[] args) {BinarySearchTree<Character> tree = new BinarySearchTree<>();System.out.println(tree.add('C'));System.out.println(tree.add('A'));System.out.println(tree.add('D'));System.out.println(tree.add('B'));System.out.println(tree.add('E'));//System.out.println(tree.add('E'));System.out.println(tree.size());System.out.println(tree.preOrder()); //[C, A, B, D, E]System.out.println(tree.inOrder()); // [A, B, C, D, E]System.out.println(tree.postOrder());//[B, A, E, D, C]}}

关于这段代码中的增加结点的非递归遍历:
在这里插入图片描述

·························································································································································································

作业:

  1. LeetCode之翻转二叉树
  2. 递归实现BST的remove(E e)方法(选做)。

这篇关于week07_day03_Tree的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/451346

相关文章

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

网络编程day03(网络体系结构、调试命令、TCP/IP对比)

目录 1》网络的体系结构 1> OSI模型  2> TCP/IP模型 3> 常见网络协议 4> DNS域名解析协议 2》 网络调试命令 1> ping:测试网络连通性(ICMP) 2> netstat   3》Dos (拒绝式服务)攻击?  4》 TCP/IP协议对比 1》网络的体系结构 网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组

java设计模式day03--(结构型模式:代理模式、适配器模式、装饰者模式、桥接模式、外观模式、组合模式、享元模式)

5,结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: 代理模式 适配器模式 装饰者模式 桥接模式 外观模式 组合模式

Sorry!Hbase的LSM Tree就是可以为所欲为!

我们先抛出一个问题: LSM树是HBase里使用的非常有创意的一种数据结构。在有代表性的关系型数据库如MySQL、SQL Server、Oracle中,数据存储与索引的基本结构就是我们耳熟能详的B树和B+树。而在一些主流的NoSQL数据库如HBase、Cassandra、LevelDB、RocksDB中,则是使用日志结构合并树(Log-structured Merge Tree,LSM Tr

【spring】does not have member field ‘com.sun.tools.javac.tree.JCTree qualid

spring-in-action-6-samples 的JDK版本 最小是11,我使用 了22: jdk21 jdk22 都与lombok 不兼容,必须使用兼容版本, 否则报错: thingsboard 的大神解释了: java: java.lang.NoSuchFieldError: Class com

代码随想录算法训练营Day03 | 链表理论基础、203.移除链表元素 、707.设计链表、206.反转链表

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 链表理论基础203.移除链表元素思路与重点 707.设计链表思路与重点 206.反转链表思路与重点 链表理论基础 C/C++的定义链表节点方式: // 单链表struct ListNode {int val; // 节点上存储的元素ListNode *next; // 指向下一个节点的指

[LeetCode] 863. All Nodes Distance K in Binary Tree

题:https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/ 题目大意 求给树中,距给定 结点 指定长度的 所有结点的val 思路 tree -> graph 、 bfs 先遍历树,并用map记录每个结点的父结点 ,将树变为图,然后 bfs。 /*** Definition for a binary tree

js实现树级递归,通过js生成tree树形菜单(递归算法)

1、效果图 需求:首先这是一个数据集—js的类型,我们需要把生成一个tree形式的对象 : var data = [{ id: 1, name: "办公管理", pid: 0 },{ id: 2, name: "请假申请", pid: 1 },{ id: 3, name: "出差申请", pid: 1 },{ id: 4, name: "请假记录", pid: 2 },{ id:

【unity实战】利用Root Motion+Blend Tree+Input System+Cinemachine制作一个简单的角色控制器

文章目录 前言动画设置Blend Tree配置角色添加刚体和碰撞体代码控制人物移动那么我们接下来调整一下相机的视角效果参考完结 前言 Input System知识参考: 【推荐100个unity插件之18】Unity 新版输入系统Input System的使用,看这篇就够了 Cinemachine虚拟相机知识参考: 【推荐100个unity插件之10】Unity最全的最详细的C