广告
返回顶部
首页 > 资讯 > 精选 >如何使用Java的平衡二叉树
  • 805
分享到

如何使用Java的平衡二叉树

2023-06-15 15:06:25 805人浏览 八月长安
摘要

这篇文章主要讲解了“如何使用Java的平衡二叉树”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Java的平衡二叉树”吧!二叉排序树可能的问题给定一个数列{1,2,3,4,5,6},要

这篇文章主要讲解了“如何使用Java的平衡二叉树”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Java的平衡二叉树”吧!

二叉排序树可能的问题

给定一个数列{1,2,3,4,5,6},要求创建一个二叉排序树(BST),分析问题所在

如何使用Java的平衡二叉树

问题分析:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 左子树全部为空,从形式上看,更像一个单链表;

  3. 插入速度没有影响;

  4. 查询速度明显降低(因为需要一次比较),不能发挥BST的优势。因为每次还要比较左子树,其查询速度,比单链表还慢。

  5. 解决方案-平衡二叉树(ALV)

基本介绍

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree),又称为AVL树,可以保证查询效率较高。

  3. 具有以下特点:它是一颗空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。平衡二叉树的常用实现方法有  红黑树、AVL、替罪羊树、Treap、伸展树等;

  4. 举例说明,下图前两个都是平衡二叉树,第一个左右子树的高度差绝对值是1,第二个左右子树高度差的绝对值是0,而第三个的左右子树高度差的绝对值是2,这样第三个就不是平衡二叉树;

如何使用Java的平衡二叉树

平衡二叉树之左旋转

步骤

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 创建一个新的节点newnode,值等于当前根节点的值。

  3. 把新节点的左子树设置成当前节点的左子树。

  4. 把新节点的右子树设置成当前节点的右子树的左子树。

  5. 把当前节点的值换为当前右子节点的值。

  6. 把当前节点的右子树设置成右子树的右子树。

  7. 把当前节点的左子树设置为新的节点。

平衡二叉树之右旋转

步骤:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 创建一个新的节点,值等于当前根的节点的值。

  3. 把新节点的右子树设置成当前节点的右子树。

  4. 把新节点的左子树设置成当前节点的左子树的右子树。

  5. 把当前节点的值换位左子节点的值。

  6. 把当前节点的左子树设置成左子树的左子树。

  7. 把当前节点的右子树设置为新的节点。

平衡二叉树之双旋转

在某些情况下,单旋转不能完成完成平衡二叉树的转换,需要进行两次旋转。

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 如果它的右子树的左子树的高度大于它的右子树的右子树的高度,需要先对右子树进行右旋转,再对当前节点进行左旋转。

  3. 如果它的左子树的右子树高度大于它的左子树的左子树高度,

  4. 需要对左子树先进行左旋转,再对当前节点进行右旋转。

代码案例

package com.xie.avl;  public class AVLTreeDemo {     public static void main(String[] args) {         int[] arr = {4, 3, 6, 5, 7, 8};         AVLTree avlTree = new AVLTree();         for (int i = 0; i < arr.length; i++) {             avlTree.add(new Node(arr[i]));         }         System.out.println("中序遍历");         avlTree.infixOrder();         System.out.println("在没有平衡处理前~~");         System.out.println("树的高度=" + avlTree.getRoot().height());         System.out.println("树的左子树的高度=" + avlTree.getRoot().leftHeight());         System.out.println("树的右子树的高度=" + avlTree.getRoot().rightHeight());     } }  class AVLTree {     private Node root;      public Node getRoot() {         return root;     }      public void setRoot(Node root) {         this.root = root;     }      //查找要删除的节点的父节点     public Node searchParent(Node node) {         if (root != null) {             return root.searchParent(node);         } else {             return null;         }     }      //查找要删除的节点     public Node search(int value) {         if (root == null) {             return null;         } else {             return root.search(value);         }     }           public int delRightTreeMin(Node node) {         Node target = node;         //循环查找左节点         while (target.left != null) {             target = target.left;         }         //删除最小节点         delNode(target.value);         return target.value;     }           public int delLeftTreeMax(Node node) {         Node target = node;         while (target.right != null) {             target = target.right;         }          //删除最大节点         delNode(target.value);         return target.value;     }      //删除节点     public void delNode(int value) {         if (root == null) {             return;         } else {             Node targetNode = search(value);             if (targetNode == null) {                 return;             }             if (targetNode == root) {                 root = null;                 return;             }             Node parentNode = searchParent(targetNode);              if (targetNode.left == null && targetNode.right == null) {                 //如果要删除的节点是叶子节点                 if (parentNode.left != null && parentNode.left.value == targetNode.value) {                     parentNode.left = null;                 }                 if (parentNode.right != null && parentNode.right.value == targetNode.value) {                     parentNode.right = null;                 }             } else if (targetNode.left != null && targetNode.right != null) {                 //如果要删除的节点是有两个子树的节点                 int minValue = delRightTreeMin(targetNode.right);                 targetNode.value = minValue;                 //上下代码删除效果一样                 //int maxValue = delLeftTreeMax(targetNode.left);                 //targetNode.value = maxValue;             } else {                 //要删除的节点是只有左子节点                 if (targetNode.left != null) {                     if (parentNode != null) {                         if (parentNode.left == targetNode) {                             parentNode.left = targetNode.left;                         } else {                             parentNode.right = targetNode.left;                         }                     } else {                         //如果父节点是空,让root换位                         root = targetNode.left;                     }                 } else {//要删除的节点是只有右子节点                     if (parentNode != null) {                         if (parentNode.left == targetNode) {                             parentNode.left = targetNode.right;                         } else {                             parentNode.right = targetNode.right;                         }                     } else {                         //如果父节点是空,让root换位                         root = targetNode.right;                     }                  }             }         }     }      //添加节点     public void add(Node node) {         if (root == null) {             root = node;         } else {             root.add(node);         }     }      //中序遍历     public void infixOrder() {         if (root != null) {             root.infixOrder();         } else {             System.out.println("二叉排序为空,不能遍历");         }     } }  class Node {     int value;     Node left;     Node right;      public Node(int value) {         this.value = value;     }           public int leftHeight() {         if (left == null) {             return 0;         }         return left.height();     }           public int rightHeight() {         if (this.right == null) {             return 0;         }         return right.height();     }           public int height() {         return Math.max(this.left == null ? 0 : this.left.height(), this.right == null ? 0 : this.right.height()) + 1;     }           public void leftRotate() {         //创建新的节点,以当前根节点的值         Node newNode = new Node(value);         //把新的节点的左子树设置为当前节点的左子树         newNode.left = left;         //把新的右子树设置为当前节点的右子树的左子树         newNode.right = right.left;         //把当前节点的值替换成右子节点的值         value = right.value;         //把当前节点的右子树设置成当前节点的右子节点的右子树         right = right.right;         //把当前的节点的左子节点(左子树),设置成新的节点         left = newNode;     }           public void rightRotate() {         //创建新的节点,以当前根节点的值         Node newNode = new Node(value);         //把新的节点的右子树设置成当前节点的右子树         newNode.right = right;         //把新的节点的左子树设置为当前节点左子树的右子树         newNode.left = left.right;         //把当前节点的值换为左子节点的值         value = left.value;         //把当前节点左子树设置成左子树的左子树         left = left.left;         //把当前节点的右子树设置新节点         right = newNode;     }           public Node searchParent(Node node) {         //如果当前节点就是要删除节点的父节点就返回         if ((this.left != null && this.left.value == node.value) ||                 (this.right != null && this.right.value == node.value)) {             return this;         } else {             if (this.left != null && node.value < this.value) {                 //如果查找的节点的值小于当前节点的值,向左子树递归查找                 return this.left.searchParent(node);             } else if (this.right != null && value >= this.value) {                 //如果查找的节点的值小于当前节点的值,向左子树递归查找                 return this.right.searchParent(node);             } else {                 return null;             }         }     }           public Node search(int value) {         if (value == this.value) {             return this;         } else if (value < this.value) {             if (this.left != null) {                 return this.left.search(value);             } else {                 return null;             }         } else {             if (this.right != null) {                 return this.right.search(value);             } else {                 return null;             }         }     }      //递归的形式添加节点,满足二叉排序树的要求     public void add(Node node) {         if (node == null) {             return;         }         if (node.value < this.value) {             if (this.left == null) {                 this.left = node;             } else {                 //递归向左子树添加                 this.left.add(node);             }         } else {             if (this.right == null) {                 this.right = node;             } else {                 //递归向右子节点添加                 this.right.add(node);             }         }          //当添加完一个节点后,如果(右子树高度-左子树高度)> 1 ,进行左旋转         if (rightHeight() - leftHeight() > 1) {             //如果它的右子树的左子树的高度大于它的右子树的右子树的高度,需要先对右子树进行右旋转,再对当前节点进行左旋转             if(right != null && right.leftHeight()>right.rightHeight()){                 right.rightRotate();                 leftRotate();             }else{                 //直接进行左旋转即可                 leftRotate();             }             return;         }          //当添加完一个节点后,如果(左子树高度-右子树高度)> 1 ,进行右旋转         if (leftHeight() - rightHeight() > 1) {             //如果它的左子树的右子树高度大于它的左子树的左子树高度,需要对左子树先进行左旋转,再对当前节点进行右旋转             if(left != null && left.rightHeight() > left.leftHeight()){                 left.leftRotate();                 rightRotate();             }else{                 //直接进行右旋转即可                 rightRotate();             }          }     }      //中序遍历     public void infixOrder() {         if (this.left != null) {             this.left.infixOrder();         }         System.out.println(this);         if (this.right != null) {             this.right.infixOrder();         }     }      @Override     public String toString() {         return "Node{" +                 "value=" + value +                 '}';     } }

感谢各位的阅读,以上就是“如何使用Java的平衡二叉树”的内容了,经过本文的学习后,相信大家对如何使用Java的平衡二叉树这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 如何使用Java的平衡二叉树

本文链接: https://www.lsjlt.com/news/280733.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用Java的平衡二叉树
    这篇文章主要讲解了“如何使用Java的平衡二叉树”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Java的平衡二叉树”吧!二叉排序树可能的问题给定一个数列{1,2,3,4,5,6},要...
    99+
    2023-06-15
  • Java如何实现平衡二叉树
    小编给大家分享一下Java如何实现平衡二叉树,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1 平衡二叉树的概述为了避免极端情况下二叉搜索树退化为链表,影响查找效率...
    99+
    2023-06-28
  • Java平衡二叉树怎么实现
    本篇内容主要讲解“Java平衡二叉树怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java平衡二叉树怎么实现”吧!什么是二叉搜索树简单来说,就是方便搜索的二叉树,是一种具备特定结构的二叉...
    99+
    2023-06-29
  • Java平衡二叉树实例分析
    这篇文章主要讲解了“Java平衡二叉树实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java平衡二叉树实例分析”吧!AVL树的引入搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以...
    99+
    2023-06-30
  • Java源码解析之平衡二叉树
    目录一、平衡二叉树的定义二、平衡二叉树的实现原理三、最终结果一、平衡二叉树的定义 平衡二叉树是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1 。它是一种高度平衡的二...
    99+
    2022-11-12
  • Java深入分析了解平衡二叉树
    目录AVL树的引入基本概念基础设计RR(左旋)LL(右旋)LR(先左旋再右旋)RL(先右旋再左旋)添加节点删除节点AVL树的引入 搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以...
    99+
    2022-11-13
  • Java中平衡二叉树的原理是什么
    Java中平衡二叉树的原理是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、平衡二叉树的定义平衡二叉树是一种二叉排序树,其中每一个节点的左子树和右子树的高...
    99+
    2023-06-15
  • Java实现红黑树(平衡二叉树)的详细过程
    目录前言红黑二叉查找树2-3树2-3树的插入操作实现红黑二叉树结尾前言 在实现红黑树之前,我们先来了解一下符号表。 符号表的描述借鉴了Algorithms第四版,详情在:https...
    99+
    2022-11-12
  • 详解如何用c++实现平衡二叉树
    目录一、概述二、平衡二叉树不平衡的情形三、调整措施3.1、单旋转3.2、双旋转四、AVL树的删除操作五、代码实现一、概述 平衡二叉树具有以下性质:它是一 棵空树或它的左右两个子树的高...
    99+
    2022-11-12
  • Python实现二叉排序树与平衡二叉树的示例代码
    目录前言1. 二叉排序树1.1 构建一棵二叉排序树1.2 二叉排序树的数据结构1.3 实现二叉排序树类中的方法:2. 平衡二叉排序树2.1 二叉平衡排序树的数据结构3. 总结前言 什...
    99+
    2022-11-10
  • 详解Java数据结构之平衡二叉树
    目录什么是二叉搜索树平衡二叉搜索树平衡二叉搜索树建树程序计算每个节点的高度计算每个节点的平衡因子合并二叉树旋转调整函数整体代码什么是二叉搜索树 简单来说,就是方便搜索的二叉树,是一种...
    99+
    2022-11-13
  • Java数据结构之平衡二叉树的实现详解
    目录定义结点结构查找算法插入算法LL 型RR 型LR 型RL 型插入方法删除算法概述实例分析代码完整代码定义 动机:二叉查找树的操作实践复杂度由树高度决定,所以希望控制树高,左右子...
    99+
    2022-11-13
  • 【C++】平衡二叉搜索树的模拟实现
    🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风翻盘。 ...
    99+
    2023-09-11
    c++ 开发语言
  • C语言平衡二叉树的示例分析
    这篇文章给大家分享的是有关C语言平衡二叉树的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一...
    99+
    2023-06-25
  • Java数据结构之平衡二叉树的原理与实现
    目录1 平衡二叉树的概述2 平衡二叉树的实现原理2.1 单旋转2.2 双旋转2.3 总结3 平衡二叉树的构建3.1 类架构3.2 查找的方法3.3 检查是否平衡的方法3.4 插入的方...
    99+
    2022-11-13
  • 如何使用C语言实现平衡二叉树数据结构算法
    目录前言一、平衡二叉树实现原理二、平衡二叉树实现算法三、全部代码前言 对于一个二叉排序树而言 它们的结构都是根据了二叉树的特性从最左子树开始在回到该结点上继续往右结点走 ...
    99+
    2022-11-12
  • C++ AVLTree高度平衡的二叉搜索树怎么实现
    这篇“C++ AVLTree高度平衡的二叉搜索树怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++&nb...
    99+
    2023-07-05
  • C++AVLTree高度平衡的二叉搜索树深入分析
    目录一、AVL树的概念二、AVL树节点的定义三、AVL树的插入四、AVL树的旋转1.左单旋2.右单旋3.左右双旋4.右左双旋五、进行验证六、AVLTree的性能一、AVL树的概念 二...
    99+
    2023-03-08
    C++ AVLTree二叉搜索树 C++高度平衡二叉搜索树
  • 如何使用LeetCode二叉树
    这篇文章主要讲解了“如何使用LeetCode二叉树”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用LeetCode二叉树”吧!树首先看看什么是树。如图...
    99+
    2022-10-19
  • java如何创建普通二叉树
    java创建二叉树 这段时间一直在复习数据结构的知识。 从最基础的开始,实现一个普通的二叉树。但发现也不那么简单。因为之前学数据结构时是用C语言写的。 指针用来对结构体的值操作比较好...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作