Java 删除AVL树中具有给定值的所有条目

Java 删除AVL树中具有给定值的所有条目,java,recursion,data-structures,tree,avl-tree,Java,Recursion,Data Structures,Tree,Avl Tree,我正在实现以下类型的AVL树AVLTree基本上树的每个节点都是键值节点,目前我正在努力使用删除所有V值的方法。这就是我所拥有的: private void deleteAll(AVLTreeNode<K,V> root, V value){ if(root == null) return; deleteAll(root.left, value); deleteAll(root.right, value); if(roo

我正在实现以下类型的AVL树
AVLTree
基本上树的每个节点都是键值节点,目前我正在努力使用删除所有
V
值的方法。这就是我所拥有的:

private void deleteAll(AVLTreeNode<K,V> root, V value){
        if(root == null) return;
        deleteAll(root.left, value);
        deleteAll(root.right, value);
        if(root.getValue().equals(value)){
            delete(root.getKey());
        }
}
发生的情况是,它正确地删除了大多数值,但有时它会留下一些必须删除的值,下面是一个示例:

DELETING ALL VALUES: 2

BEFORE DELETION OF EVERY: 2

               ->2
          ->0
     ->1
               ->2
          ->1
               ->1
->1
          ->0
     ->2
          ->2

AFTER DELETION

               ->2
          ->0
     ->1
          ->2
->1
          ->1
     ->1
          ->0
Time used: 0 ms tree size: 8
-------------------------------------------

Does tree contain value: 2? true
编辑:

下面是这个类的所有代码

package structure.tree.balanced;

import structure.array.Array;
import structure.node.Node;
import structure.tree.Tree;

public class AVLTree<K extends Comparable<K>,V> extends Tree<AVLTree.AVLTreeNode<K, V>> {

    private static final long serialVersionUID = 5046115177325966348L;

    public boolean containsValue(V value) {
        return containsValue(((AVLTreeNode<K,V>) super.getRoot()), value);
    }

    private boolean containsValue(AVLTreeNode<K,V> root, V value){
        if(root == null) return false;
        else {
            if(root.getValue().equals(value)) return true;
            else return containsValue(root.getLeft(), value) || containsValue(root.getRight(), value);
        }
    }

    public boolean containsKey(K key){
        return containsKey(((AVLTreeNode<K,V>) super.getRoot()), key);
    }

    private boolean containsKey(AVLTreeNode<K,V> root, K key){
        if(root == null) return false;
        else {
            if(root.getKey().compareTo(key) < 0) return containsKey(root.getRight(), key);
            else if(root.getKey().compareTo(key) > 0) return containsKey(root.getLeft(), key);
            else return true;
        }
    }

    public void delete(K key){
        super.setRoot(delete(super.getRoot(), key));
    }

    private AVLTreeNode<K,V> delete(AVLTreeNode<K,V> root, K key) {
        if (root == null) {
            return root;
        } else if (root.getKey().compareTo(key) > 0) {
            root.setLeft(delete(root.left, key));
        } else if (root.getKey().compareTo(key) < 0) {
            root.setRight(delete(root.right, key));
        } else {
            if (root.left == null || root.right == null) {
                root = (root.left == null) ? root.right : root.left;
            } else {
                AVLTreeNode<K,V> mostLeftChild = minValueNode(root.right);
                root.key = mostLeftChild.getKey();
                root.value = mostLeftChild.getValue();
                root.setRight(delete(root.right, root.key));
            }
            if(size > 0) size--;
        }
        if (root != null) {
            root = rebalance(root);
        }
        return root;
    }

    public void deleteAll(V value){
        deleteAll(super.getRoot(), value);
    }

    private void deleteAll(AVLTreeNode<K,V> root, V value){
        if(root == null) return;
        deleteAll(root.left, value);
        deleteAll(root.right, value);
        if(root.getValue().equals(value)) delete(root.getKey());
    }

    public V get(K key){
        return get(super.getRoot(), key);
    }

    private V get(AVLTreeNode<K, V> root, K key) {
        if(root.getKey().compareTo(key) == 0) return root.getValue();
        else if(root.getKey().compareTo(key) > 0) return get(root.getLeft(), key);
        else return get(root.getRight(), key);
    }

    private int getBalance(AVLTreeNode<K,V> n) {
        return (n == null) ? 0 : height(n.getRight()) - height(n.getLeft());
    }

    private int height(AVLTreeNode<K,V> n) {
        return n == null ? -1 : n.getHeight();
    }

    public void insert(K key, V value) {
        size++;
        super.setRoot(insert(super.getRoot(), key, value));
    }

    private AVLTreeNode<K,V> insert(AVLTreeNode<K,V> root, K key, V value){
        if (root == null) {
            return new AVLTreeNode<K,V>(key, value);
        } else if (root.getKey().compareTo(key) > 0) {
            root.setLeft(insert(root.getLeft(), key, value));
        } else if (root.getKey().compareTo(key) < 0) {
            root.setRight(insert(root.getRight(), key, value));
        } else {
            size--;
            throw new RuntimeException("duplicate Key!");
        }
        return rebalance(root);
    }

    private AVLTreeNode<K,V> minValueNode(AVLTreeNode<K,V> root){
        if(root == null) return null;
        else {
            if(root.getLeft() != null) return minValueNode(root.getLeft());
            else return root;
        }
    }

    private AVLTreeNode<K,V> rebalance(AVLTreeNode<K,V> z) {
        updateHeight(z);
        int balance = getBalance(z);
        if (balance > 1) {
            if (height(z.getRight().getRight()) > height(z.getRight().getLeft())) {
                z = rotateLeft(z);
            } else {
                z.setRight(rotateRight(z.getRight()));
                z = rotateLeft(z);
            }
        } else if (balance < -1) {
            if (height(z.getLeft().getLeft()) > height(z.getLeft().getRight()))
                z = rotateRight(z);
            else {
                z.setLeft(rotateLeft(z.getLeft()));
                z = rotateRight(z);
            }
        }
        return z;
    }

    public void replace(K key, V newValue) {
        replace(super.getRoot(), key, newValue);
    }

    private void replace(AVLTreeNode<K, V> root, K key, V newValue) {
        if(root != null){
            if(root.getKey().compareTo(key) == 0) root.setValue(newValue);
            else if(root.getKey().compareTo(key) > 0) replace(root.getLeft(), key, newValue);
            else replace(root.getRight(), key, newValue);
        }
    }

    public void replaceAll(V oldValue, V newValue){
        replaceAll(super.getRoot(), oldValue, newValue);
    }

    private void replaceAll(AVLTreeNode<K, V> root, V oldValue, V newValue){
        if(root == null) return;
        if(root.getValue().equals(oldValue)) root.setValue(newValue);
        replaceAll(root.left, oldValue, newValue);
        replaceAll(root.right, oldValue, newValue);
    }

    private AVLTreeNode<K,V> rotateLeft(AVLTreeNode<K,V> y){
        AVLTreeNode<K,V> x = y.getRight();
        AVLTreeNode<K,V> z = x.getLeft();
        x.setLeft(y);
        y.setRight(z);
        updateHeight(y);
        updateHeight(x);
        return x;
    }

    private AVLTreeNode<K,V> rotateRight(AVLTreeNode<K,V> y){
        AVLTreeNode<K,V> x = y.getLeft();
        AVLTreeNode<K,V> z = x.getRight();
        x.setRight(y);
        y.setLeft(z);
        updateHeight(y);
        updateHeight(x);
        return x;
    }

    public Object[] toArray(){
        return toArray(super.getRoot(), new Array<>(size()));
    }

    private Object[] toArray(AVLTreeNode<K,V> root, Array<AVLTreeNode<K,V>> arr){
        if(root != null){
            toArray(root.left, arr);
            arr.insert(root);
            toArray(root.right, arr);
        }
        return arr.toArray();
    }

    private void updateHeight(AVLTreeNode<K,V> root){
        root.setHeight(1 + Math.max(height(root.getLeft()), height(root.getRight())));
    }

    public static class AVLTreeNode<K extends Comparable<K>, V> implements Node<V> {

        private static final long serialVersionUID = -2099221188924293375L;
        private AVLTreeNode<K,V> left, right;
        private K key;
        private V value;
        private int height = 0;
    
        public AVLTreeNode(K key, V value){
            this.key = key;
            this.value = value;
        }
    
        public K getKey() {
            return key;
        }
    
        @SuppressWarnings("unused")
        private void setKey(K key) {
            this.key = key;
        }
    
        public AVLTreeNode<K,V> getLeft() {
            return left;
        }
    
        protected void setLeft(AVLTreeNode<K,V> left) {
            this.left = left;
        }
    
        public AVLTreeNode<K,V> getRight() {
            return right;
        }
    
        protected void setRight(AVLTreeNode<K,V> right) {
            this.right = right;
        }
    
        @Override
        public String toString() {
            return "{\"key\":"+key+",\"value\":"+getValue()+"}";
        }
    
        @Override
        public V getValue() {
            return value;
        }
    
        @Override
        public void setValue(V value) {
            this.value = value;
        }
    
        public int getHeight() {
            return height;
        }
    
        protected void setHeight(int height) {
            this.height = height;
        }
    
        public int getBalance() {
            return (left != null ? left.getHeight() : 0) - (right != null ? right.getHeight() : 0); 
        }
        
    }

}
package structure.tree.balanced;
导入structure.array.array;
导入structure.node.node;
导入structure.tree.tree;
公共类AVLTree扩展树{
私有静态最终长serialVersionUID=504615177325966348L;
公共布尔值包含值(V值){
返回containsValue(((AVLTreeNode)super.getRoot()),value);
}
私有布尔包含值(AVLTreeNode根,V值){
if(root==null)返回false;
否则{
if(root.getValue().equals(value))返回true;
否则返回containsValue(root.getLeft(),value)| containsValue(root.getRight(),value);
}
}
公共布尔containsKey(K键){
返回containsKey(((AVLTreeNode)super.getRoot()),key);
}
私有布尔containsKey(AVLTreeNode根,K键){
if(root==null)返回false;
否则{
if(root.getKey().compareTo(key)<0)返回containsKey(root.getRight(),key);
else if(root.getKey().compareTo(key)>0)返回containsKey(root.getLeft(),key);
否则返回true;
}
}
公共无效删除(K键){
setRoot(delete(super.getRoot(),key));
}
专用AVLTreeNode删除(AVLTreeNode根目录,K键){
if(root==null){
返回根;
}如果(root.getKey().compareTo(key)>0),则为else{
setLeft(删除(root.left,key));
}else if(root.getKey().compareTo(key)<0){
root.setRight(删除(root.right,key));
}否则{
if(root.left==null | | root.right==null){
root=(root.left==null)?root.right:root.left;
}否则{
AVLTreeNode mostLeftChild=minValueNode(root.right);
root.key=mostLeftChild.getKey();
root.value=mostLeftChild.getValue();
setRight(删除(root.right,root.key));
}
如果(大小>0)大小--;
}
if(root!=null){
根=再平衡(根);
}
返回根;
}
公共void deleteAll(V值){
deleteAll(super.getRoot(),value);
}
私有void deleteAll(AVLTreeNode根,V值){
if(root==null)返回;
deleteAll(root.left,值);
deleteAll(root.right,value);
如果(root.getValue().equals(value))删除(root.getKey());
}
公共V get(K键){
返回get(super.getRoot(),key);
}
私有V get(AVLTreeNode根,K键){
if(root.getKey().compareTo(key)==0)返回root.getValue();
else if(root.getKey().compareTo(key)>0)返回get(root.getLeft(),key);
否则返回get(root.getRight(),key);
}
私有int getBalance(AVLTreeNode n){
返回值(n==null)?0:height(n.getRight())-height(n.getLeft());
}
专用内部高度(AVLTreeNode n){
返回n==null?-1:n.getHeight();
}
公共无效插入(K键,V值){
大小++;
setRoot(插入(super.getRoot(),键,值));
}
专用AVLTreeNode插入(AVLTreeNode根,K键,V值){
if(root==null){
返回新的AVLTreeNode(键,值);
}如果(root.getKey().compareTo(key)>0),则为else{
setLeft(插入(root.getLeft(),键,值));
}else if(root.getKey().compareTo(key)<0){
setRight(插入(root.getRight(),键,值));
}否则{
大小--;
抛出新的RuntimeException(“复制键!”);
}
返回再平衡(根);
}
专用AVLTreeNode minValueNode(AVLTreeNode根目录){
if(root==null)返回null;
否则{
if(root.getLeft()!=null)返回minValueNode(root.getLeft());
否则返回根;
}
}
私有AVLTreeNode重新平衡(AVLTreeNode z){
更新高度(z);
int balance=getBalance(z);
如果(余额>1){
如果(高度(z.getRight().getRight())>高度(z.getRight().getLeft()){
z=旋转英尺(z);
}否则{
z、 setRight(rotateRight(z.getRight());
z=旋转英尺(z);
}
}否则如果(余额<-1){
如果(高度(z.getLeft().getLeft())>高度(z.getLeft().getRight())
z=旋转方向(z);
否则{
z、 setLeft(rotateLeft(z.getLeft());
z=旋转方向(z);
}
}
返回z;
}
公共无效替换(K键,V新值){
替换(super.getRoot(),key,newValue);
}
私有void replace(AVLTreeNode根,K键,V newValue){
if(root!=null){
如果(root.getKey().compareTo(key)==0)root.setValue(newValue);
如果(root.getKey().compareTo(key)>0)替换(root.getLeft(),key,newValue);
else替换(root.getRight(),键,newValue);
}
}
公共void replaceAll(V旧值,V新值){
replaceAll(super.getRoot(),oldValue,newValue);
}
私有void replaceAll(AVLTreeNode根、V oldValue、V newValue){
if(root==null)返回;
如果(root.getValue().equals(oldValue))root.setValue(newValue);
replaceAll(root.left、oldValue、newValue);
replaceAll(root.right、oldValue、newValue);
}
专用AVLTreeNode rotateLeft(AVLTreeNode y){
AVLTreeNode x=y.getRight();
AVLTreeNode z=x.getLeft();
x、 左(y);
y、 塞特里格
package structure.tree.balanced;

import structure.array.Array;
import structure.node.Node;
import structure.tree.Tree;

public class AVLTree<K extends Comparable<K>,V> extends Tree<AVLTree.AVLTreeNode<K, V>> {

    private static final long serialVersionUID = 5046115177325966348L;

    public boolean containsValue(V value) {
        return containsValue(((AVLTreeNode<K,V>) super.getRoot()), value);
    }

    private boolean containsValue(AVLTreeNode<K,V> root, V value){
        if(root == null) return false;
        else {
            if(root.getValue().equals(value)) return true;
            else return containsValue(root.getLeft(), value) || containsValue(root.getRight(), value);
        }
    }

    public boolean containsKey(K key){
        return containsKey(((AVLTreeNode<K,V>) super.getRoot()), key);
    }

    private boolean containsKey(AVLTreeNode<K,V> root, K key){
        if(root == null) return false;
        else {
            if(root.getKey().compareTo(key) < 0) return containsKey(root.getRight(), key);
            else if(root.getKey().compareTo(key) > 0) return containsKey(root.getLeft(), key);
            else return true;
        }
    }

    public void delete(K key){
        super.setRoot(delete(super.getRoot(), key));
    }

    private AVLTreeNode<K,V> delete(AVLTreeNode<K,V> root, K key) {
        if (root == null) {
            return root;
        } else if (root.getKey().compareTo(key) > 0) {
            root.setLeft(delete(root.left, key));
        } else if (root.getKey().compareTo(key) < 0) {
            root.setRight(delete(root.right, key));
        } else {
            if (root.left == null || root.right == null) {
                root = (root.left == null) ? root.right : root.left;
            } else {
                AVLTreeNode<K,V> mostLeftChild = minValueNode(root.right);
                root.key = mostLeftChild.getKey();
                root.value = mostLeftChild.getValue();
                root.setRight(delete(root.right, root.key));
            }
            if(size > 0) size--;
        }
        if (root != null) {
            root = rebalance(root);
        }
        return root;
    }

    public void deleteAll(V value){
        deleteAll(super.getRoot(), value);
    }

    private void deleteAll(AVLTreeNode<K,V> root, V value){
        if(root == null) return;
        deleteAll(root.left, value);
        deleteAll(root.right, value);
        if(root.getValue().equals(value)) delete(root.getKey());
    }

    public V get(K key){
        return get(super.getRoot(), key);
    }

    private V get(AVLTreeNode<K, V> root, K key) {
        if(root.getKey().compareTo(key) == 0) return root.getValue();
        else if(root.getKey().compareTo(key) > 0) return get(root.getLeft(), key);
        else return get(root.getRight(), key);
    }

    private int getBalance(AVLTreeNode<K,V> n) {
        return (n == null) ? 0 : height(n.getRight()) - height(n.getLeft());
    }

    private int height(AVLTreeNode<K,V> n) {
        return n == null ? -1 : n.getHeight();
    }

    public void insert(K key, V value) {
        size++;
        super.setRoot(insert(super.getRoot(), key, value));
    }

    private AVLTreeNode<K,V> insert(AVLTreeNode<K,V> root, K key, V value){
        if (root == null) {
            return new AVLTreeNode<K,V>(key, value);
        } else if (root.getKey().compareTo(key) > 0) {
            root.setLeft(insert(root.getLeft(), key, value));
        } else if (root.getKey().compareTo(key) < 0) {
            root.setRight(insert(root.getRight(), key, value));
        } else {
            size--;
            throw new RuntimeException("duplicate Key!");
        }
        return rebalance(root);
    }

    private AVLTreeNode<K,V> minValueNode(AVLTreeNode<K,V> root){
        if(root == null) return null;
        else {
            if(root.getLeft() != null) return minValueNode(root.getLeft());
            else return root;
        }
    }

    private AVLTreeNode<K,V> rebalance(AVLTreeNode<K,V> z) {
        updateHeight(z);
        int balance = getBalance(z);
        if (balance > 1) {
            if (height(z.getRight().getRight()) > height(z.getRight().getLeft())) {
                z = rotateLeft(z);
            } else {
                z.setRight(rotateRight(z.getRight()));
                z = rotateLeft(z);
            }
        } else if (balance < -1) {
            if (height(z.getLeft().getLeft()) > height(z.getLeft().getRight()))
                z = rotateRight(z);
            else {
                z.setLeft(rotateLeft(z.getLeft()));
                z = rotateRight(z);
            }
        }
        return z;
    }

    public void replace(K key, V newValue) {
        replace(super.getRoot(), key, newValue);
    }

    private void replace(AVLTreeNode<K, V> root, K key, V newValue) {
        if(root != null){
            if(root.getKey().compareTo(key) == 0) root.setValue(newValue);
            else if(root.getKey().compareTo(key) > 0) replace(root.getLeft(), key, newValue);
            else replace(root.getRight(), key, newValue);
        }
    }

    public void replaceAll(V oldValue, V newValue){
        replaceAll(super.getRoot(), oldValue, newValue);
    }

    private void replaceAll(AVLTreeNode<K, V> root, V oldValue, V newValue){
        if(root == null) return;
        if(root.getValue().equals(oldValue)) root.setValue(newValue);
        replaceAll(root.left, oldValue, newValue);
        replaceAll(root.right, oldValue, newValue);
    }

    private AVLTreeNode<K,V> rotateLeft(AVLTreeNode<K,V> y){
        AVLTreeNode<K,V> x = y.getRight();
        AVLTreeNode<K,V> z = x.getLeft();
        x.setLeft(y);
        y.setRight(z);
        updateHeight(y);
        updateHeight(x);
        return x;
    }

    private AVLTreeNode<K,V> rotateRight(AVLTreeNode<K,V> y){
        AVLTreeNode<K,V> x = y.getLeft();
        AVLTreeNode<K,V> z = x.getRight();
        x.setRight(y);
        y.setLeft(z);
        updateHeight(y);
        updateHeight(x);
        return x;
    }

    public Object[] toArray(){
        return toArray(super.getRoot(), new Array<>(size()));
    }

    private Object[] toArray(AVLTreeNode<K,V> root, Array<AVLTreeNode<K,V>> arr){
        if(root != null){
            toArray(root.left, arr);
            arr.insert(root);
            toArray(root.right, arr);
        }
        return arr.toArray();
    }

    private void updateHeight(AVLTreeNode<K,V> root){
        root.setHeight(1 + Math.max(height(root.getLeft()), height(root.getRight())));
    }

    public static class AVLTreeNode<K extends Comparable<K>, V> implements Node<V> {

        private static final long serialVersionUID = -2099221188924293375L;
        private AVLTreeNode<K,V> left, right;
        private K key;
        private V value;
        private int height = 0;
    
        public AVLTreeNode(K key, V value){
            this.key = key;
            this.value = value;
        }
    
        public K getKey() {
            return key;
        }
    
        @SuppressWarnings("unused")
        private void setKey(K key) {
            this.key = key;
        }
    
        public AVLTreeNode<K,V> getLeft() {
            return left;
        }
    
        protected void setLeft(AVLTreeNode<K,V> left) {
            this.left = left;
        }
    
        public AVLTreeNode<K,V> getRight() {
            return right;
        }
    
        protected void setRight(AVLTreeNode<K,V> right) {
            this.right = right;
        }
    
        @Override
        public String toString() {
            return "{\"key\":"+key+",\"value\":"+getValue()+"}";
        }
    
        @Override
        public V getValue() {
            return value;
        }
    
        @Override
        public void setValue(V value) {
            this.value = value;
        }
    
        public int getHeight() {
            return height;
        }
    
        protected void setHeight(int height) {
            this.height = height;
        }
    
        public int getBalance() {
            return (left != null ? left.getHeight() : 0) - (right != null ? right.getHeight() : 0); 
        }
        
    }

}
package structure.tree;

import structure.Structure;
import structure.node.Node;

/**
 * A Tree is a {@Structure} that uses {@Node} as value.
 */
public abstract class Tree<N extends Node<?>> {
    
    private static final long serialVersionUID = -2524427972418434522L;
    private N root;

    public void clear() {
        root = null;
        size = 0;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public N getRoot() {
        return root;
    }

    protected void setRoot(N value) {
        this.root = value;
    }

}
AVLTree<Integer,Integer> avlt = new AVLTree<Integer,Integer>();
Random r = new Random();
for(int i = 1; i <= SIZE; i++){
    avlt.insert(i, r.nextInt(keySize));
}
int vdel = r.nextInt(keySize);
avlt.deleteAll(vdel);
assertEquals(false, avlt.containsValue(vdel));
     2->X
    /    \
1->X      3->X
              \
               4->O
2->X
    \
     3->X
         \
          4->O
     3->X
   /     \
2->X     4->O
3->X
    \
     4->O
  public static class AVLTreeNode<K extends Comparable<K>, V> implements Node<V> {

    private AVLTreeNode<K,V> left, right, parent;
    private final K key;
    private V value;
    private int height = 0;

    public AVLTreeNode(K key, V value){
      this.key = key;
      this.value = value;
    }

    protected void setLeft(AVLTreeNode<K,V> left) {
      this.left = left;
      if( left!=null ) {
        left.parent = this;
      }
    }

    public AVLTreeNode<K,V> getNext() {
      AVLTreeNode<K,V> next;

      // If a right branch exists, the next node is the left-most node in the right branch.
      if( right!=null ) {
        next = right;
        while( next.left!=null ) {
          next = next.left;
        }
        return next;
      }

      // The closest parent of which this is a left-branch descendant is the next node
      next = this;
      while( next.parent!=null ) {
        if( next.parent.left==next ) {
          return next.parent;
        }
        next = next.parent;
      }

      // no next node
      return null;
    }


    protected void setRight(AVLTreeNode<K,V> right) {
      this.right = right;
      if( right!=null ) {
        right.parent = this;
      }
    }


    ... rest of class is unchanged
  }
  public void insert(K key, V value) {
    size++;
    AVLTreeNode<K,V> newRoot = insert(super.getRoot(),key,value);
    newRoot.parent = null;
    super.setRoot(newRoot);
  }

  public void delete(K key){
    AVLTreeNode<K,V> newRoot = delete(super.getRoot(), key);
    if( newRoot!=null ) {
      newRoot.parent = null;
    }
    super.setRoot(newRoot);
  }
  private AVLTreeNode<K,V> delete(AVLTreeNode<K,V> root, K key) {
    if (root == null) {
      return root;
    } else if (root.getKey().compareTo(key) > 0) {
      root.setLeft(delete(root.left, key));
    } else if (root.getKey().compareTo(key) < 0) {
      root.setRight(delete(root.right, key));
    } else {
      if (root.left == null || root.right == null) {
        root = (root.left == null) ? root.right : root.left;
      } else {
        // Promote the next node to replace root.
        AVLTreeNode<K,V> mostLeftChild = minValueNode(root.right);
        mostLeftChild.setRight(delete(root.right, mostLeftChild.key));
        mostLeftChild.setLeft(root.left);
        root = mostLeftChild;
      }
      if(size > 0) size--;
    }
    if (root != null) {
      root = rebalance(root);
    }
    return root;
  }
  public static class AVLNodeIterator<K extends Comparable<K>,V> implements Iterator<AVLTreeNode<K,V>> {
    AVLTree<K,V> tree;
    AVLTreeNode<K,V> current;
    AVLTreeNode<K,V> next;

    public AVLNodeIterator(AVLTree<K,V> tree) {
      this.tree = tree;
      current = null;
      next = tree.minValueNode(tree.getRoot());
    }


    @Override
    public boolean hasNext() {
      return next!=null;
    }


    @Override
    public AVLTreeNode<K, V> next() {
      if( next==null ) {
        throw new NoSuchElementException();
      }
      current = next;
      next = current.getNext();
      return current;
    }


    @Override
    public void remove() {
      if( current==null ) {
        throw new IllegalStateException();
      }
      tree.delete(current.getKey());
      current=null;
    }

  }

  public void deleteAll(V value){
    Iterator<AVLTreeNode<K,V>> iterator = new AVLNodeIterator<>(this);
    while( iterator.hasNext()) {
      AVLTreeNode<K,V> node = iterator.next();
      if( node.getValue().equals(value) ) {
        iterator.remove();
      }
    }
  }