2024年Java数据结构-二叉树(BinaryTree)(九)(2),从草根到百万年薪程序员的十年风雨之路

一线互联网大厂Java核心面试题库

image

正逢面试跳槽季,给大家整理了大厂问到的一些面试真题,由于文章长度限制,只给大家展示了部分题目,更多Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等已整理上传,感兴趣的朋友可以看看支持一波!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

二叉树的结点类

根据对图的观察,我们发现二叉树其实就是由一个一个的结点及其之间的关系组成的,按照面向对象的思想,我们设计一个结点类来描述结点这个事物。

二叉查找树实现

插入方法put实现思想:

  1. 如果当前树中没有任何一个结点,则直接把新结点当做根结点使用

  2. 如果当前树不为空,则从根结点开始:

2.1 如果新结点的key小于当前结点的key,则继续找当前结点的左子结点;

2.2 如果新结点的key大于当前结点的key,则继续找当前结点的右子结点;

2.3 如果新结点的key等于当前结点的key,则树中已经存在这样的结点,替换该结点的value值即可;

查询方法get实现思想:

从根节点开始:

  1. 如果要查询的key小于当前结点的key,则继续找当前结点的左子结点;

  2. 如果要查询的key大于当前结点的key,则继续找当前结点的右子结点;

  3. 如果要查询的key等于当前结点的key,则树中返回当前结点的value;

删除方法delete实现思想:

  1. 找到被删除结点;

  2. 找到被删除结点右子树中的最小结点minNode;

  3. 删除右子树中的最小结点;

  4. 让被删除结点的左子树称为最小结点minNode的左子树,让被删除结点的右子树;称为最小结点minNode的右子树 ;

  5. 让被删除结点的父节点指向最小结点minNode;

代码实现

public class BinaryTree<Key extends Comparable,Value> {

private Node root;

private int N;

private class Node{

Key key;

Value value;

Node left;

Node right;

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

this.key = key;

this.value = value;

this.left = left;

this.right = right;

}

}

public int size(){

return this.N;

}

public void put(Key key,Value value){

this.root = put(this.root,key,value);

}

/**

  • 重载put方法,实现递归

  • @param node

  • @param key

  • @param value

*/

private Node put(Node node,Key key,Value value){

// 如果当前树中没有任何一个结点,则直接把新结点当做根结点使用

if(node == null){

this.N ++;

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

}else {

// 如果当前树不为空,则从根结点开始:

// 2.1 如果新结点的key小于当前结点的key,则继续找当前结点的左子结点;

int i = key.compareTo(node.key);

if(i<0){

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

}else if(i>0){

// 2.2 如果新结点的key大于当前结点的key,则继续找当前结点的右子结点;

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

}else {

// 2.3 如果新结点的key等于当前结点的key,则树中已经存在这样的结点,替换该结点的value值即可;

node.value = value;

}

}

return node;

}

public Value get(Key key){

// 从根节点开始:

return get(this.root,key);

}

/**

  • 重载get方法,实现递归

  • @param node

  • @param key

  • @return value

*/

private Value get(Node node,Key key){

if(node == null){

return null;

}else {

int i = key.compareTo(node.key);

if(i<0){

// 如果要查询的key小于当前结点的key,则继续找当前结点的左子结点;

return get(node.left,key);

}else if(i>0){

// 如果要查询的key大于当前结点的key,则继续找当前结点的右子结点;

return get(node.right,key);

}else {

// 如果要查询的key等于当前结点的key,则树中返回当前结点的value;

return node.value;

}

}

}

public void delete(Key key){

delete(root,key);

}

/**

  • 重载put方法,实现递归

  • @param node

  • @param key

  • @return Node

*/

private Node delete(Node node,Key key){

if(node == null){

return null;

}

int i = key.compareTo(node.key);

if(i<0){

// 如果要查询的key小于当前结点的key,则继续找当前结点的左子结点

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

}else if(i>0){

// 如果要查询的key大于当前结点的key,则继续找当前结点的右子结点;

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

}else {

// 如果当前节点的右节点为空,则返回左节点

if(node.right == null){

return node.left;

}

// 如果当前节点的左节点为空,则返回右节点

if(node.left == null){

return node.right;

}

// 如果两个节点都存在,则去找 右节点的最小值;

Node midNode = node.right;

while (midNode.left != null){

midNode = midNode.left;

}

// 删除右节点上的最小节点

// 找到右节点最小值

Node temp = node.right;

// 如果右节点temp就是最小节点,表示temp没有左节点了,那就把temp的右节点赋值为 node 的右节点。达到删除teme 的效果

if(temp.left == null){

node.right = temp.right;

}else {

// 否则循环寻找最小值,并且删除最小值

while (temp.left != null){

// 如果右节点最小节点 temp ,存在右节点则把右节点赋值给temp,否则为空,并返回

if (temp.left.right != null) {

temp.left = temp.left.right;

break;

}else if(temp.left.left == null){

temp.left = null;

}else {

temp = temp.left;

}

}

}

midNode.left = node.left;

midNode.right = node.right;

node = midNode;

N–;

}

return node;

}

}

查找二叉树中最小的键

public Key min(){

return min(root).key;

}

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

private Node min(Node x){

if(x.left!=null){

return min(x.left);

}else{

return x;

}

}

查找二叉树中最大的键

//找出整个树中最 大的键

public Key max(){

return max(root).key;

}

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

private Node max(Node x){

if(x.right!=null){

return max(x.right);

}else{

return x;

}

}

二叉树的基础遍历

二叉树的遍历主要有三种:

  1. 前序遍历;

先访问根结点,然后再访问左子树,最后访问右子树 ;

  1. 中序遍历;

先访问左子树,中间访问根节点,最后访问右子树 ;

  1. 后序遍历;

先访问左子树,再访问右子树,最后访问根节点;

举个例子:

先(根)序遍历(根左右):E B A D C G F H

中(根)序遍历(左根右) : A B C D E F G H

后(根)序遍历(左右根) : A C D B F H G E

代码实现

  • 前序遍历

// 前序遍历 先访问根结点,然后再访问左子树,最后访问右子树 ;

public MyQueue preErgodic(){

MyQueue keys = new MyQueue<>();

preErgodic(this.root,keys);

return keys;

};

private void preErgodic(Node x,MyQueue keys){

if(x == null){

return;

}

keys.push(x.key);

if(x.left!= null){

preErgodic(x.left,keys);

}

if(x.right !=null){

preErgodic(x.right,keys);

}

}

  • 中序遍历

// 中序遍历 先访问左子树,中间访问根节点,最后访问右子树 ;

public MyQueue midErgodic(){

MyQueue keys = new MyQueue<>();

midErgodic(this.root,keys);

return keys;

}

private void midErgodic(Node x,MyQueue keys){

if(x == null){

return;

}

if(x.left!= null){

midErgodic(x.left,keys);

}

keys.push(x.key);

if(x.right !=null){

midErgodic(x.right,keys);

}

}

  • 后序遍历

// 后续遍历 先访问左子树,再访问右子树,最后访问根节点;

public MyQueue afterErgodic(){

MyQueue keys = new MyQueue<>();

afterErgodic(this.root,keys);

return keys;

}

private void afterErgodic(Node x,MyQueue keys){

if(x == null){

return;

}

if(x.left!= null){

afterErgodic(x.left,keys);

}

if(x.right !=null){

afterErgodic(x.right,keys);

}

keys.push(x.key);

}

二叉树的层序遍历

层序遍历,就是从根节点(第一层)开始,依次向下,获取每一层所有结点的值,有二叉树如下:

总结

其他的内容都可以按照路线图里面整理出来的知识点逐一去熟悉,学习,消化,不建议你去看书学习,最好是多看一些视频,把不懂地方反复看,学习了一节视频内容第二天一定要去复习,并总结成思维导图,形成树状知识网络结构,方便日后复习。

这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来

目录:

部分内容截图:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

erErgodic(x.left,keys);

}

if(x.right !=null){

afterErgodic(x.right,keys);

}

keys.push(x.key);

}

二叉树的层序遍历

层序遍历,就是从根节点(第一层)开始,依次向下,获取每一层所有结点的值,有二叉树如下:

总结

其他的内容都可以按照路线图里面整理出来的知识点逐一去熟悉,学习,消化,不建议你去看书学习,最好是多看一些视频,把不懂地方反复看,学习了一节视频内容第二天一定要去复习,并总结成思维导图,形成树状知识网络结构,方便日后复习。

这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来

目录:

[外链图片转存中…(img-sZhtpJM8-1714846373784)]

部分内容截图:

[外链图片转存中…(img-9qXpzT4z-1714846373785)]

[外链图片转存中…(img-0mYCnoyx-1714846373786)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值