Java数据结构-二叉树(BinaryTree)(九)

蜂信物联FastBee平台https://gitee.com/beecue/fastbee

阿里资料开源项目https://gitee.com/vip204888

百度低代码前端框架https://gitee.com/baidu/amis

OpenHarmony开源项目https://gitcode.com/openharmony

仓颉编程语言开放项目https://gitcode.com/Cangjie

完全二叉树:

叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树;

二叉查找树的设计

二叉树的结点类

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

二叉查找树实现

插入方法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){

写在最后

为了这次面试,也收集了很多的面试题!

以下是部分面试题截图

Java程序员秋招三面蚂蚁金服,我总结了所有面试题,也不过如此
ue 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){

写在最后

为了这次面试,也收集了很多的面试题!

以下是部分面试题截图

[外链图片转存中…(img-mRWxaSSw-1725173119069)]

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点:左子节点和右子节点。以下是一个简单的Java实现二叉树的例子: ```java // 定义二叉树节点类 class TreeNode { int val; TreeNode left; TreeNode right; public TreeNode(int val) { this.val = val; this.left = null; this.right = null; } } // 构建二叉树 public class BinaryTree { TreeNode root; public BinaryTree(int val) { this.root = new TreeNode(val); } // 插入节点 public void insert(int val) { TreeNode newNode = new TreeNode(val); if (root == null) { root = newNode; } else { TreeNode current = root; TreeNode parent; while (true) { parent = current; if (val < current.val) { current = current.left; if (current == null) { parent.left = newNode; return; } } else { current = current.right; if (current == null) { parent.right = newNode; return; } } } } } // 先序遍历 public void preOrderTraversal(TreeNode node) { if (node != null) { System.out.print(node.val + " "); preOrderTraversal(node.left); preOrderTraversal(node.right); } } // 中序遍历 public void inOrderTraversal(TreeNode node) { if (node != null) { inOrderTraversal(node.left); System.out.print(node.val + " "); inOrderTraversal(node.right); } } // 后序遍历 public void postOrderTraversal(TreeNode node) { if (node != null) { postOrderTraversal(node.left); postOrderTraversal(node.right); System.out.print(node.val + " "); } } } // 创建二叉树并进行遍历 public class Main { public static void main(String[] args) { BinaryTree binaryTree = new BinaryTree(5); binaryTree.insert(3); binaryTree.insert(7); binaryTree.insert(2); binaryTree.insert(4); binaryTree.insert(6); binaryTree.insert(8); System.out.println("先序遍历结果:"); binaryTree.preOrderTraversal(binaryTree.root); System.out.println(); System.out.println("中序遍历结果:"); binaryTree.inOrderTraversal(binaryTree.root); System.out.println(); System.out.println("后序遍历结果:"); binaryTree.postOrderTraversal(binaryTree.root); System.out.println(); } } ``` 这个例子展示了如何构建一个二叉树,并对其进行先序、中序和后序遍历。你可以根据需要修改节点的值和插入顺序来构建不同的二叉树
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值