eliminación de datos binarios

Cuatro lograr la eliminación de datos binario

1, los datos de borrado no hay niños
2, eliminar los datos mientras que no tienen nodos secundarios
3, suprimir el nodo hijo izquierdo y el nodo hijo derecho no está vacía
4, elimine el nodo raíz

Ejemplo:

Con referencia a la figura:

Aquí Insertar imagen Descripción

interface Two<T> {
    public void add(Comparable<T> data);    //数据增加

    public int size();  //用于判断数据是否进行了存储

    public Object[] toArray();  //输出

    public boolean inquire(T data); //查询

    public void remove(T data); //删除数据
}

class TwoImpl<T> implements Two<T> {
    private Node root;  //根节点
    private int size;
    private int footer;
    private Object[] resultData;

    @Override
    //增加
    public void add(Comparable<T> data) {
        if (data == null) {
            return;
        }
        Node node = new Node(data);
        if (this.root == null) {    //根节点
            this.root = node;
        } else {
            this.root.addNode(this.root, node);
        }
        ++this.size;
    }

    @Override
    //获取数据的个数
    public int size() {
        return this.size;
    }

    @Override
    //数取数据输出
    public Object[] toArray() {
        if (this.size() == 0) {
            return null;
        }
        this.footer = 0;
        this.resultData = new Object[this.size];
        this.root.toArrayNode();
        return this.resultData;
    }

    @Override
    //判断数据是否存在
    public boolean inquire(T data) {
        //判断有没有数据,,没有返回false
        if (this.size() == 0) {
            return false;
        }
        //有数据进入inquireNode()内去查找数据
        return this.root.inquireNode(data);
    }

    @Override
    //输出数据
    public void remove(T data) {
        if (this.inquire(data)) { //判断数据是否存在
            if (this.root.data.compareTo(data) == 0) {
                this.root = this.delete(data);
            } else {
                this.delete(data);
            }
            --this.size;
        }
    }

    private Node delete(T data) {
        Node sonNode = null;
        Node thisNode = this.root.removeNode(data);
        /*
		1、删除的数据没有子节点
        */
        
        if (thisNode.right == null && thisNode.left == null) {
            if (thisNode.parent != null) {
                if (thisNode.parent.data.compareTo(data) <= 0) {
                    //断绝引用关系
                    thisNode.parent.right = null;
                } else {
                    //断绝引用关系
                    thisNode.parent.left = null;
                }
            }
            //判断要删除的数据在父节点的左边还是右边
            //解除节点和父节点的引用
            thisNode.parent = null;
        }

		/*
		2、删除的数据有一边有子节点
        */
        
        if ((thisNode.right != null && thisNode.left == null)
                || (thisNode.right == null && thisNode.left != null)) {
            //存储要删除的节点下面的子节点
            //删除节点在父节点的右边
                if (thisNode.right != null) {
                    //把值赋给sonNode
                    sonNode = thisNode.right;
                } else { //删除节点在父节点的左边
                    sonNode = thisNode.left;
                }
                if (thisNode.parent != null) {
                //判断要删除的数据在父节点的什么位置
                if (thisNode.parent.data.compareTo(data) <= 0) {
                    thisNode.parent.right = sonNode;
                } else {
                    thisNode.parent.left = sonNode;
                }
            }
            //修改父节点
            sonNode.parent = thisNode.parent;
        }
		/*
		3、删除左子节点和右子节点都不为空的节点
		
		4、根节点的删除
        */
        
        if (thisNode.left != null && thisNode.right != null) {
            sonNode = thisNode.right;
                while (sonNode.left != null) {
                    sonNode = sonNode.left;
                }
                 /*
                当thisNode.right == sonNode时
                sonNode.parent.left = null会使
                thisNode.left断开引用会出错
                放在sonNode.right != null判断之前先断开
                在把移动节点的右子节点放到移动节点的父节点的左边
                */
                if (thisNode.right != sonNode) {
                    //断开引用
                    sonNode.parent.left = null;
                }

                //当最左边的节点有右子节点时
                if (sonNode.right != null) {
                    //右子节点的等于移动节点的左边
                    sonNode.parent.left = sonNode.right;
                    sonNode.right.parent = sonNode.parent;
                }


                //将移动节点顶替要删除的节点
                sonNode.parent = thisNode.parent;
                if (thisNode.right != sonNode) {
                    sonNode.right = thisNode.right;
                }
                sonNode.left = thisNode.left;
                //当删除节点的父节点小于删除节点时(用于判断删除节点在父节点的什么位置)
                if (thisNode.parent != null) {
                    if (thisNode.parent.data.compareTo(data) <= 0) {
                    /*
                    移动节点等于删除节点的父节点的右子节点
                    将移动节点放到删除节点的父节点的相应方向的位置下
                     */
                        thisNode.parent.right = sonNode;
                    } else {
                    /*
                    移动节点等于删除节点的父节点的左子节点
                    将移动节点放到删除节点的父节点的相应方向的位置下
                     */
                        thisNode.parent.left = sonNode;
                    }
                }
        }
        return sonNode;
    }

    /********************内部类************************/
    private class Node {
        private Comparable<T> data; //数据
        private Node left;      //左节点
        private Node right;     //右节点
        private Node parent;    //父节点

        public Node(Comparable<T> data) {
            this.data = data;
        }

        /**
         * this.data
         *
         * @param parentNode 父节点
         * @param node       内部类实例(用于传递data数据)
         */
        public void addNode(Node parentNode, Node node) {
            if (this.data.compareTo((T) node.data) <= 0) {  //当前节点this.root小于传入节点
                if (this.right == null) {
                    this.right = node;
                    node.parent = parentNode;
                } else {
                    this.right.addNode(this.right, node);
                }
            } else {
                if (this.left == null) {
                    this.left = node;
                    node.parent = parentNode;
                } else {
                    this.left.addNode(this.left, node);
                }
            }
        }

        public void toArrayNode() { //中序解析
            if (this.left != null) {  //把左边的数据全部取出再去右边的
                this.left.toArrayNode();
            }
            TwoImpl.this.resultData[TwoImpl.this.footer++] = this.data;
            if (this.right != null) {   //左边的数据取完后才会进入右边
                this.right.toArrayNode();
            }
        }

        /**
         * 获取数据
         *
         * @param data 查询的数据
         * @return 是否存在查询的数据
         */
        public boolean inquireNode(T data) {
            //判断数据是否为根节点
            if (this.data.compareTo(data) == 0) {
                return true;
            } else {
                //当数据大于根节点时(this.data < data)
                if (this.data.compareTo(data) < 0) {
                    //判断右节点有没有值
                    if (this.right != null) {
                        //递归调用去匹配值,到最后时匹配就会在判断时不满足返回false
                        return this.right.inquireNode(data);
                    } else {
                        return false;
                    }
                } else {    //当数据小于根节点时(this.data > data)
                    //判断左节点有没有值
                    if (this.left != null) {
                        //递归调用去匹配值,到最后时匹配就会在判断时不满足返回false
                        return this.left.inquireNode(data);
                    } else {
                        return false;
                    }
                }
            }
        }

        public Node removeNode(T data) {
            //数据等于根节点
            if (this.data.compareTo(data) == 0) {
                return this;    //通过这个返回要删除的数据
            } else {
                if (this.data.compareTo(data) < 0) {
                    //返回的是无数次递归后的找到的数据,其实就是利用上面的return this返回数据;
                    return this.right.removeNode(data);
                } else {
                    return this.left.removeNode(data);
                }
            }
        }
    }
}

public class Demo01 {
    public static void main(String[] args) {
        Two<Member> two = new TwoImpl<>();
        two.add(new Member("孙七", 27));
        two.add(new Member("赵六", 26));
        two.add(new Member("王五", 25));
        two.add(new Member("张三", 23));
        two.add(new Member("李四1", 24));
        two.add(new Member("李四2", 55));
        two.add(new Member("李四3", 40));
        two.add(new Member("李四4", 38));
        two.add(new Member("李四5", 29));
        two.add(new Member("李四6", 21));
        two.add(new Member("李四7", 19));
        two.add(new Member("李四11", 62));
        two.add(new Member("李四8", 51));
        two.add(new Member("李四9", 34));
        two.add(new Member("李四10", 56));
        two.add(new Member("李四12", 72));
        two.add(new Member("李四13", 45));
        two.add(new Member("李四46", 46));
        two.add(new Member("李四14", 33));
        two.add(new Member("李四15", 31));
        //删除根节点
        two.remove(new Member("孙七", 27));
        //two.remove(new Member("李四3", 40));
        System.out.println(Arrays.toString(two.toArray()));
    }
}

resultados:

[name='李四7, age=19
, name='李四6, age=21
, name='张三, age=23
, name='李四1, age=24
, name='王五, age=25
, name='赵六, age=26
, name='李四5, age=29
, name='李四15, age=31
, name='李四14, age=33
, name='李四9, age=34
, name='李四4, age=38
, name='李四3, age=40
, name='李四13, age=45
, name='李四46, age=46
, name='李四8, age=51
, name='李四2, age=55
, name='李四10, age=56
, name='李四11, age=62
, name='李四12, age=72
]
Publicado 61 artículos originales · ganado elogios 0 · Vistas 2196

Supongo que te gusta

Origin blog.csdn.net/sabstarb/article/details/104285107
Recomendado
Clasificación