package com.haojiangbo.avltree; //AVL二叉查找树 public class AvlTree { public Node root; public void add(Node node){ if(null == root){ root = node; return; } root.add(node); } public int getHigth(){ return root.getHigth(); } public int getRigthHigth(){ return root.rigthHigth(); } public int getLeftHigth(){ return root.left.leftHigth(); } public Node get(int v){ if(null == root){ return null; } return root.get(v); } //中序遍历 public void zhongxu(){ if(null == root){ return; } root.zhongxu(); } public AvlTree.Node searhParent(int v){ if(null == this.root){ return null; } else{ return this.root.searhParent(v); } } public void del(int v){ if(root == null){ return; } Node target = get(v); //如果节点的root节点不存在 说明为根节点 处理根节点的逻辑 if(target == root){ if(null == target.left && null == target.rigth){ root = null; }else if(null != target.left && null != target.rigth){ Node temp = root.left; del(root.left.value); root.value = temp.value; }else{ if(target.rigth != null){ root = target.rigth; }else if(target.left != null){ root = target.left; } } return; } Node parent = searhParent(v); //被删除节点不是根节点 3种情况的删除方法 //1 叶子节点 左右子树都为空 //2 单边节点 左树 或者右树为空值 父节点指向删除节点的子节点 //3 全树节点 左右节点都不为空的情况 找到当前节点的1级左子树 然后删除 把1级左子树的值替换掉当前节点 if(target.left == null && target.rigth == null){ if(null != parent.left && target.value == parent.left.value){ parent.left = null; }else{ parent.rigth = null; } }else if(target.left != null && target.rigth != null){ Node temp = target.left; del(target.left.value); target.value = temp.value; }else{ if(null != target.left){ if(null != parent.left && parent.left.value == target.value){ parent.left = target.left; }else{ parent.rigth = target.left; } }else{ if(null != parent.left && parent.left.value == target.value){ parent.left = target.rigth; }else{ parent.rigth = target.rigth; } } } } /** * 接地啊对象 */ public static class Node{ public int value; //左叶子节点 public Node left; //右叶子节点 public Node rigth; /* //父节点 public Node parent;*/ @Override public String toString() { return "Node{" + "value=" + value + '}'; } public Node (int value){ this.value = value; } //左子树高度 public int leftHigth(){ if(null == left){ return 0; } return left.getHigth(); } //右子树高度 public int rigthHigth(){ if(null == rigth){ return 0; } return rigth.getHigth(); } //树的高度 public int getHigth(){ return Math.max(left == null ? 0:left.getHigth() ,rigth == null? 0: rigth.getHigth())+1; } /** * 左旋转 */ public void leftRotate(){ //创建新节点已当前根节点的值 Node newNode = new Node(value); //新节点的左子树为当前节点的左子树 newNode.left = left; //新节点的右子树为当前节点右子树的左子树 newNode.rigth = rigth.left; //当前节点的值替换为右子节点的值 value = rigth.value; //当前节点的右子树设置为 右子树的右子树 rigth = rigth.rigth; //当前左子节点设置为新节点 left = newNode; } /** * 右旋转 */ public void rigthRotate(){ //创建1个新节点 Node newNode = new Node(value); //新节点的右节点 指向当前节点的右节点 newNode.rigth = rigth; //新节点的左节点指向当前节点的左节点的右节点 newNode.left = left.rigth; //当前节点的值 等于左节点的值 等于把当前节点的左节点 删除了 value = left.value; //当前节点的左节点指向左节点的左节点 left = left.left; //当前节点的右节点指向新节点 rigth = newNode; } public Node get(int value){ if(value == this.value){ return this; } if(value < this.value && null != this.left){ return this.left.get(value); }else if(value >= this.value && null != this.rigth){ return this.rigth.get(value); }else{ return null; } } public void zhongxu(){ if(null != this.left){ this.left.zhongxu(); } System.out.println(this.value); if(null != this.rigth){ this.rigth.zhongxu(); } } public void add(Node node){ if(node.value < this.value){ if(this.left == null){ this.left = node; }else{ this.left.add(node); } }else{ if(this.rigth == null){ this.rigth = node; }else{ this.rigth.add(node); } } //如果右子树减左子树的高度 大于1 if((rigthHigth() - leftHigth()) > 1){ if(null != rigth && rigth.leftHigth() > rigth.rigthHigth()){ rigth.rigthRotate(); } leftRotate(); return; } //此处的判断条件是个非常耗费性能的递归函数 所以上面执行完之后 马上return if(leftHigth() - rigthHigth() > 1){ //如果当前节点的右子树的高度大于左子树高度 //就先进行一次左旋转 if(null != left && left.rigthHigth() > left.leftHigth()){ left.leftRotate(); } rigthRotate(); return; } } /** * 查找父节点 * @param v * @return */ public AvlTree.Node searhParent(int v){ if((this.left != null && this.left.value == v) || (this.rigth != null && this.rigth.value == v) ){ return this; } if(null != this.left && this.value > v){ return this.left.searhParent(v); }else if (null != this.rigth && this.value <= v){ return this.rigth.searhParent(v); }else { return null; } } } }
avl 平衡二叉树
猜你喜欢
转载自blog.csdn.net/qq_37421368/article/details/97316709
今日推荐
周排行