数据结构实战java实现二叉查找树
来源:互联网 发布:淘宝找客户要好评 编辑:程序博客网 时间:2024/05/21 19:25
此方法参考自数据结构与算法分析-java描述
二叉树简介
形如这样的上级节点的值大于它的左支所有值,小于它的右支所有值,就叫做二叉树。
二叉树的作用
- 迅速查找
- 构造表达式
不平衡二叉树的链表实现
public class MyBinarySearchTree<AnyType extends Comparable<? super AnyType>> { //ci此内部类构建每个的节点 private static class BinaryNode<AnyType> { //声明节点数据,左支和右支 AnyType element; BinaryNode<AnyType> left; BinaryNode<AnyType> right; //初始化一个节点 BinaryNode( AnyType theElement ) { this( theElement, null, null); } //创建一个节点 BinaryNode( AnyType theElement, BinaryNode<AnyType> leftTree, BinaryNode<AnyType> rightTree ) { element = theElement; left = leftTree; right = rightTree; } } //声明字段 root 的类型为 BinaryNode<AnyType> private BinaryNode<AnyType> root; //初始化二叉查找树 public MyBinarySearchTree() { root = null; } //清空树 public void makeEmpty() { root = null; } //判断树是否为空 public boolean isEmpty() { return root == null; } //判断树是否存在 含有项value的节点 public boolean contains( AnyType value ) { return contains( value, root ); } public AnyType findMin() { try { if ( isEmpty( )) throw new UnderflowException("树上没有叶子"); } catch(UnderflowException e) { System.out.println(e); } return findMin( root ). element; } public AnyType findMax() { try { if ( isEmpty( )) throw new UnderflowException("树上没有叶子"); //return findMin( root ). element; } catch(UnderflowException e) { System.out.println(e); } return findMax( root ). element; } public void insert ( AnyType value ) { root = insert( value, root ); } public void remove( AnyType value ) { root = remove( value, root ); } public void printTree() { printTree( root); } //判断 value是否在 tree中 private boolean contains( AnyType value, BinaryNode<AnyType> tree ) { // 递归退出条件 if ( tree == null ) return false; //将 value 与 节点的值进行比较 int compareResult = value.compareTo( tree.element ); if ( compareResult < 0 ) return contains( value, tree.left ); else if ( compareResult > 0 ) return contains( value, tree.right ); // 递归退出条件 else return true; } //一直向左支走就是最小值 private BinaryNode<AnyType> findMin( BinaryNode<AnyType> tree ) { if ( tree == null ) return null; else if ( tree.left == null ) return tree; return findMin( tree.left ); } //一直向右支走就是最大值 private BinaryNode<AnyType> findMax( BinaryNode<AnyType> tree ) { if ( tree == null ) return null; else if ( tree.right == null ) return tree; return findMin( tree.right ); } //二叉树插入方法,此实现对于重复得数值不进行插入 private BinaryNode<AnyType> insert( AnyType value, BinaryNode<AnyType> tree ) { if ( tree == null) return new BinaryNode<AnyType>( value, null, null ); int compareResult = value.compareTo( tree.element); if ( compareResult < 0) tree.left = insert( value, tree.left ); else if ( compareResult > 0 ) tree.right = insert( value, tree.right ); // java的语言设定中,如果你创建了一个 有返回值得函数 那么在函数的第一级必须要有return。 else ; return tree; } //删除节点值后需要对剩下的节点进行重排以维持一个二叉树 private BinaryNode<AnyType> remove( AnyType value, BinaryNode<AnyType> tree ) { //删除共有4种可能性 //1 删除节点是叶片 //2 删除节点有一个子树 //3 删除节点有俩个子树 //4 删除节点不存在 if ( tree == null ) return tree; int compareResult = value.compareTo( tree.element ); if (compareResult < 0 ) tree.left = remove( value, tree.left ); else if ( compareResult > 0 ) tree.right = remove( value, tree.right ); //俩个子树的情况 else if ( tree.left != null && tree.right != null) { //将右子树的最小值替代 tree的数值 tree.element = findMin( tree.right ).element; //转变为只有一个子树的情况 tree.right = remove( tree.element, tree.right ); } else //java 三元表达式 tree = ( tree.left != null) ? tree.left : tree.right; return tree; } //打印树我选择后序遍历这种方式 private void printTree( BinaryNode<AnyType> tree ) { if (tree == null) return; printTree(tree.left); printTree(tree.right); System.out.println(tree.element); } private static class UnderflowException extends Exception { public UnderflowException() { } public UnderflowException(String message) { super(message); } } }
测试代码
//测试代码 public static void main(String[] args) { MyBinarySearchTree test = new MyBinarySearchTree(); test.insert(3); test.insert(1); test.insert(4); //System.out.println(test.root.right.element); test.printTree(); }
运行结果
143
写法分析
此种方法实现的二叉树如输入一串连续的排练好的数字,此时树就会都由只有右树的节点构成。并不能很好的进行查找。
一种最古老的二叉平衡树(AVL)的实现
AVL :Adelson-Velskii 和 Landis的名字缩写。
AVL树的实现
在上面的基础上
//此内部类构建每个AVL树的节点 private static class AvlNode<AnyType> { AnyType element; AvlNode<AnyType> left; AvlNode<AnyType> right; int height; //构建一个节点 AvlNode( AnyType theElement ) { this( theElement, null, null); } AvlNode( AnyType theElement, AvlNode<AnyType> lt, AvlNode<AnyType> rt ) { element = theElement; left = lt; right = rt; height = 0; } } //返回 当前节点的深度 private int height( AvlNode<AnyType> tree ) { return tree == null ? -1 : tree.height; } //avl插入 private AvlNode<AnyType> AVLinsert( AnyType value, AvlNode<AnyType> tree ) { //递归退出条件 if ( tree == null ) return new AvlNode<AnyType>( value, null, null); int compareResult = value.compareTo( tree.element); if( compareResult < 0) { tree.left = AVLinsert(value, tree.left); // 如果左树的深度要比右树深度大2,调用旋转。 if (height( tree.left) - height( tree.right) == 2) // 如果 value 比左树的节点大调用左单旋 ,否则左双旋。 if ( value.compareTo( tree.left.element) < 0 ) tree = rotateWithLeftChild( tree); else tree = doubleWithleftChild( tree); } else if ( compareResult > 0) { tree.right = AVLinsert(value, tree.right); // 如果右树的深度要比左树深度大2,调用旋转。 if (height( tree.right) - height( tree.left) == 2) // 如果 value 比右树的节点大调用右单旋 ,否则右双旋。 if ( value.compareTo( tree.right.element) < 0 ) tree = rotateWithRightChild( tree); else tree = doubleWithRightChild( tree); } else ; //更新深度值 tree.height = Math.max(height(tree.left), height(tree.right)) + 1; return tree; } //左单旋转 private AvlNode<AnyType> rotateWithLeftChild( AvlNode<AnyType> k2 ) { AvlNode<AnyType> k1 = k2.left; k2.left = k1.right; k1.right = k2; k2.height = Math.max(height( k2.left), height( k2.right)) + 1; k1.height = Math.max(height( k1.left), k2.height) + 1; return k1; } //右单旋转 private AvlNode<AnyType> rotateWithRightChild( AvlNode<AnyType> k1 ) { AvlNode<AnyType> k2 = k1.right; k1.right = k2.left; k2.left = k1; k1.height = Math.max(height( k1.left), height( k1.right)) + 1; k2.height = Math.max(height( k2.right), k1.height) + 1; return k2; } //左双旋转 private AvlNode<AnyType> doubleWithleftChild( AvlNode<AnyType> k3 ) { //转化为俩次单旋转 k3.left = rotateWithRightChild(k3.left); return rotateWithLeftChild(k3); } //右双旋转 private AvlNode<AnyType> doubleWithRightChild( AvlNode<AnyType> k3 ) { //转化为俩次单旋转 k3.right = rotateWithLeftChild(k3.right); return rotateWithRightChild(k3); }
AVL树的分析
插入时的旋转操作
而双旋转可以看做时俩次单旋转
阅读全文
0 0
- 数据结构实战java实现二叉查找树
- 数据结构--二叉查找树的java实现
- Java实现数据结构之二叉查找树
- 数据结构之Java实现二叉查找树
- 数据结构实战java实现二叉堆
- 二叉查找树的数据结构以及实现(JAVA)
- 重温数据结构:二叉查找树的java实现
- 数据结构学习笔记之Java实现二叉查找树
- Java实现数据结构——二叉查找树
- C 实现数据结构二叉查找树
- 数据结构二叉查找树C++实现
- [数据结构]二叉查找树 简单实现
- 数据结构:JavaScript实现二叉查找树
- 数据结构:二叉查找树(C语言实现)
- 数据结构:二叉数查找树基本实现
- java数据结构--二叉树与查找树
- Java数据结构课程设计 二叉树查找
- 数据结构(Java)——二叉查找树
- 极光推送 状态栏图标显示不全(原创)
- 1124 字符统计 C++/C DEV-C++
- UPX 教程
- lora无线水表技术和NB-IOT无线水表相比,有什么不同?
- 2017住博会圆满落幕北京毕加索公司应邀参会演讲
- 数据结构实战java实现二叉查找树
- 为设备服务的文件系统sysfs--kobject和kset的关系
- continue语句
- 深度学习所需的python-学习笔记2
- php后台判断用户用的是什么浏览器浏览
- web前端初学技能——5大web前端核心技能
- C语言里字符串的解析
- 我的第一个python web开发框架本地部署前端访问服务器
- [14-1]资料总结