数据结构与算法-自定义二叉树API

本文介绍了如何使用自定义的BinaryTree类进行字符串键值对的插入、查找、删除操作,以及查找树中的最小值和最大值,通过代码实例展示了如何在主函数中进行操作并进行前序遍历。
摘要由CSDN通过智能技术生成

树中最大值是:8

E-----2

B-----2

A-----1

D-----4

C-----3

G-----7

F-----6

H-----8

测试类

public static void main(String[] args) {

BinaryTree<String, String> tree = new BinaryTree<>();

tree.put(“E”, “5”);

tree.put(“B”, “2”);

tree.put(“G”, “7”);

tree.put(“A”, “1”);

tree.put(“D”, “4”);

tree.put(“F”, “6”);

tree.put(“H”, “8”);

tree.put(“C”, “3”);

System.out.println(“key 为E 的值是:”+tree.get(“E”));

System.out.println(“key 为B 的值是:”+tree.get(“B”));

System.out.println(“树中元素个数是:”+tree.size());

System.out.println(“树中最小值是:”+ tree.min());

System.out.println(“树中最大值是:”+ tree.max());

//前序遍历

Queue keys = tree.preErgodic();

for (String key : keys){

System.out.println(key+“-----”+tree.get(key));

}

}

BinaryTree类

package cn.bloghut.tree;

/**

  • @author by 闲言

  • @classname BinaryTree

  • @description 自定义二叉树api

  • @date 2021/7/21 10:53

*/

public class BinaryTree<Key extends Comparable, Value> {

//存储元素个数

private int size;

//头结点

private Node head;

public class Node {

//记录左子结点

private Node left;

//记录右子结点

private Node right;

//记录key

private Key key;

//记录value

private Value value;

//初始化

public Node(Key key, Value value, Node left, Node right) {

this.key = key;

this.value = value;

this.left = left;

this.right = right;

}

}

/**

  • 初始化

*/

public BinaryTree() {

this.size = 0;

}

/**

  • 往树中插入一个键值对

  • @param key

  • @param value

*/

public void put(Key key, Value value) {

head = put(head, key, value);

}

/**

  • 在指定树x上,添加一个键值对,并返回添加后的新树

  • @param x

  • @param key

  • @param value

*/

public Node put(Node x, Key key, Value value) {

//判断根结点是否为空

if (x == null) {

size++;

return new Node(key, value, null, null);

} else {

//比较x 结点和key的大小

int cmp = key.compareTo(x.key);

//判断key 是否大于 当前结点的键,找出当前右子树

if (cmp > 0) {

x.right = put(x.right, key, value);

} else if (cmp < 0) {

//判断key 是否小于 当前结点的键,找出当前左子树

x.left = put(x.left, key, value);

} else {

//判断key 是否等于 当前结点的键,说明该键已经存在,则替换该值

x.value = value;

}

}

return x;

}

/**

  • 根据key 返回value

  • @param key

  • @return

*/

public Value get(Key key) {

return get(head, key);

}

/**

  • 从指定树中找出对应的值

  • @param x

  • @param key

  • @return

*/

public Value get(Node x, Key key) {

if (x == null) {

return null;

}

int cmp = key.compareTo(x.key);

if (cmp > 0) {

x.value = get(x.right, key);

} else if (cmp < 0) {

x.value = get(x.left, key);

} else {

return x.value;

}

return x.value;

}

/**

  • 删除key 对应的结点

  • @param key

*/

public void delete(Key key) {

head = delete(head, key);

}

/**

  • 删除指定结点x 中 的key,并返回删除后的树

  • @param x

  • @param key

  • @return

*/

public Node delete(Node x, Key key) {

if (x == null) {

return null;

}

int cmp = key.compareTo(x.key);

if (cmp > 0) {

//新结点的key大于当前结点的key,继续找当前结点的右子结点

x.right = delete(x.right, key);

} else if (cmp < 0) {

//新结点的key小于当前结点的key,继续找当前结点的左子结点

x.left = delete(x.left, key);

} else {

//新结点的key等于当前结点的key,当前x就是要删除的结点

//1.如果当前结点的右子树不存在,则直接返回当前结点的左子结点

if (x.right == null) {

return x.left;

}

//2.如果当前结点的左子树不存在,则直接返回当前结点的右子结点

if (x.left == null) {

return x.right;

}

//3.当前结点的左右子树都存在

Node minNode = x.right;

//3.1找到右子树中最小的结点

while (minNode.left != null) {

minNode = minNode.left;

}

//3.2删除右子树中最小的结点

Node n = x.right;

while (n.left != null) {

if (n.left.left == null) {

n.left = null;

} else {

n = n.left;

}

}

//3.3让被删除结点的左子树称为最小结点minNode的左子树,让被删除结点的右子树称为最小结点minNode的右子树

minNode.left = x.left;

minNode.right = x.right;

//3.4让被删除结点的父节点指向最小结点minNode

x = minNode;

//个数-1

size–;

}

return x;

}

/**

  • 获取元素个数

  • @return

*/

public int size() {

return size;

}

/**

  • 判断是否为空

  • @return

*/

public boolean isEmpty() {

return size == 0;

}

/**

  • 查找整个树中最小的键

  • @return

*/

public Value min() {

return min(head).value;

}

/**

  • 在指定树x 中找出最小键所在的结点

  • @param x

  • @return

*/

public Node min(Node x) {

//需要判断x 有没有左子结点,如果有,则继续向左找,如果没有,则x 就是最小键所在的结点

if (x.left != null) {

return min(x.left);

} else {

return x;

}

}

/**

  • 查找整个树中最大的键

  • @return

*/

public Value max() {

return max(head).value;

}

/**

  • 在指定树x 中找出最大键所在的结点

  • @param x

  • @return

*/

private Node max(Node x) {

//判断x还有没有右子结点,如果有,则继续向有查找,如果没有,则x就是最大键所在的结点

if (x.right != null) {

return max(x.right);

} else {

return x;

}

}

/**

  • 获取整个树中所有的键

  • @return

*/

public Queue preErgodic() {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。

上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料

有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
😕/img-community.csdnimg.cn/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

总结

虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。

[外链图片转存中…(img-RWbp2UAJ-1713712932042)]

[外链图片转存中…(img-pFq2i98z-1713712932042)]

上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料

有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 29
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值