Estructura de datos de Java: la realización del árbol.

Tabla de contenido

1. La razón de la existencia de la estructura de árbol

2. Diagrama esquemático del árbol.

3. Tipos de árboles

 Cuarto, la implementación del código del árbol binario.

4.1 Clase de nodo

4.2 Recorrido del árbol binario ordenado

 4.3 Construir un árbol binario ordenado

 4.4 Implementación recursiva del árbol binario

4.5, recorrer recursivamente el árbol binario

4.6 Borrado de árbol binario ordenado

 4.6.1 Eliminación de nodos hoja

 4.6.2 Eliminar un nodo con un solo subárbol

 4.6.3 Eliminar un nodo con dos subárboles

 4.6.4, implementación del código de eliminación de nodos


1. La razón de la existencia de la estructura de árbol

1. Análisis del método de almacenamiento de matrices Ventajas
: acceda a los elementos a través de la siguiente tabla y la velocidad es rápida. Para matrices ordenadas, la búsqueda binaria se puede utilizar para mejorar la velocidad de recuperación.
Desventajas: si desea recuperar un valor específico, la eficiencia es relativamente baja
2. Análisis del método de almacenamiento en cadena
Ventajas: hasta cierto punto, optimice el método de almacenamiento de matriz (por ejemplo, para insertar un nodo, solo necesita vincular el nodo insertado a la lista enlazada y eliminarlo también es muy eficiente).
Desventajas: al buscar, la eficiencia sigue siendo relativamente baja, por ejemplo (para recuperar un cierto valor, debe atravesar desde el primer nodo) 3. El
análisis de los métodos de almacenamiento de árboles
puede mejorar la eficiencia del almacenamiento y la lectura de datos, como utilizando árboles de clasificación binarios, se garantiza la velocidad de recuperación de datos. Al mismo tiempo, también puede garantizar la velocidad de inserción, eliminación y modificación de datos.

2. Diagrama esquemático del árbol.

3. Tipos de árboles

 1. Hay muchos tipos de árboles, y cada nodo solo puede tener como máximo dos nodos secundarios en una forma denominada árbol binario
2. Los nodos secundarios de un árbol binario se dividen en nodos izquierdos y nodos derechos

 3. Si todos los nodos hoja del árbol binario están en la última capa y el número de puntos de resumen = 2^n-1, (n es el número de capas), lo llamamos número binario completo.

 4. Si todos los nodos de hoja del árbol binario están en la última capa o en la penúltima capa, y los nodos de hoja de la última capa son continuos a la izquierda, y los nodos de hoja de la penúltima capa son continuas a la derecha, lo llamamos un árbol binario completo.

 Cuarto, la implementación del código del árbol binario.

4.1 Clase de nodo

public class TreeNode {
    private TreeNode leftTreeNode;
    private TreeNode rightTreeNode;
    private Integer value;

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public TreeNode(Integer value){
        this.value = value;
    }

    public TreeNode getLeftTreeNode() {
        return leftTreeNode;
    }

    public void setLeftTreeNode(TreeNode leftTreeNode) {
        this.leftTreeNode = leftTreeNode;
    }

    public TreeNode getRightTreeNode() {
        return rightTreeNode;
    }

    public void setRightTreeNode(TreeNode rightTreeNode) {
        this.rightTreeNode = rightTreeNode;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "leftTreeNode=" + leftTreeNode +
                ", rightTreeNode=" + rightTreeNode +
                ", value=" + value +
                '}';
    }
}

4.2 Recorrido del árbol binario ordenado

 4.3 Construir un árbol binario ordenado

//树管理类
public class BinaryTree {
	//构建有序二叉树
	TreeNode root;
	public void insert(int value) {
		//新建节点
		TreeNode newNode=new TreeNode(value);
		if(root==null) {
			root=newNode;
		}else {
			//定义游标来遍历树
			TreeNode currentNode=root;
			//定义一个游标指向currentNode的前一个
			TreeNode parentNode=null;
			while(true) {
				parentNode=currentNode;
				if(newNode.getValue()>currentNode.getValue()) {
					currentNode=currentNode.getRightTreeNode();
					if(currentNode==null) {
						//数据插入
						parentNode.setRightTreeNode(newNode);
						return;
					}
				}else {
					currentNode=currentNode.getLeftTreeNode();
					if(currentNode==null) {
						//数据插入
						parentNode.setLeftTreeNode(newNode);
						return;
					}
				}
			}
		}
		
	}

 4.4 Implementación recursiva del árbol binario

//递归插入二叉树节点
	// 递归出口和递归表达式
    // f(node,value) = f(node.left,value)     node.getLeftTreeNode == null;
    // = f(node.right,value)    node.getRightTreeNode == null;
	public void insertDiGui(TreeNode node,int value) {
		//创建节点
		TreeNode newNode=new TreeNode(value);
		if(root==null) {
			root=newNode;
			return;
		}
		if(node.getValue()>newNode.getValue()) {
			if(node.getLeftTreeNode()!=null) {
				insertDiGui(node.getLeftTreeNode(), value);
			}else {
				node.setLeftTreeNode(newNode);
			}
		}else {
			if(node.getRightTreeNode()!=null) {
				insertDiGui(node.getRightTreeNode(), value);
			}else {
				node.setRightTreeNode(newNode);
			}
		}
	}

4.5, recorrer recursivamente el árbol binario

Recorrido en orden:

//二叉树的遍历-----深度优先遍历------前中后序遍历
	//先序遍历
	public void beforeOrder(TreeNode treeNode) {
		if(treeNode==null) {
			return;
		}
		System.out.println(" "+treeNode.getValue()+" ");
		beforeOrder(treeNode.getLeftTreeNode());
		beforeOrder(treeNode.getRightTreeNode());
	}
	//中序遍历
	public void midOrder(TreeNode treeNode) {
		if(treeNode==null) {
			return;
		}
		afterOrder(treeNode.getLeftTreeNode());
		System.out.println(" "+treeNode.getValue()+" ");
		afterOrder(treeNode.getRightTreeNode());
	}
	//后序遍历
	public void afterOrder(TreeNode treeNode) {
		if(treeNode==null) {
			return;
		}
		afterOrder(treeNode.getLeftTreeNode());
		afterOrder(treeNode.getRightTreeNode());
		System.out.println(" "+treeNode.getValue()+" ");
	}

4.6 Borrado de árbol binario ordenado

 4.6.1 Eliminación de nodos hoja

 4.6.2 Eliminar un nodo con un solo subárbol

 4.6.3 Eliminar un nodo con dos subárboles

 4.6.4, implementación del código de eliminación de nodos

/**
         * 删除节点
     * @param node  删的的树
     * @param value 删除的值
     */
	public void delNode(TreeNode node,int value) {
		if(node==null) {
			System.out.println("这是一颗空树");
			return;
		}
		//找到要删除的节点
		TreeNode targetNode=search(node, value);
		if(targetNode==null) {
			return;
		}
		//判断这棵树是不是只有一个节点
		if(node.getLeftTreeNode()==null&&node.getRightTreeNode()==null) {
			root=null;
			return;
		}
		//找到要删除节点的父节点
		TreeNode parent=SearchParent(node, value);
		//删除叶子节点
		if(targetNode.getLeftTreeNode()==null&&targetNode.getRightTreeNode()==null) {
			// 确定targetNode是parentNode的左子树还是右子树
			if(parent.getLeftTreeNode()!=null&&parent.getLeftTreeNode().getValue()==value) {
				parent.setLeftTreeNode(null);
			}else if(parent.getRightTreeNode()!=null && parent.getRightTreeNode().getValue() == value){ //右子节点
                parent.setRightTreeNode(null);
            }
		//删除两个子树的节点
		}else if(targetNode.getLeftTreeNode()!= null && targetNode.getRightTreeNode()!=null){   
            int minValue = delRightTreeMin(targetNode.getRightTreeNode());
            targetNode.setValue(minValue);
			
		}else {//删除只有一个子树的节点
            //要删除的节点有左孩子
            if(targetNode.getLeftTreeNode()!=null){
                if(parent.getLeftTreeNode()!=null && parent.getLeftTreeNode().getValue() == value){
                    //targetNode是parent节点的左子树
                    parent.setLeftTreeNode(targetNode.getLeftTreeNode());
                }else {
                    //targetNode是parent节点的右子树
                    parent.setRightTreeNode(targetNode.getLeftTreeNode());
                }
            }else {//要删除的节点有右孩子
                if(parent.getRightTreeNode()!=null && parent.getRightTreeNode().getValue() == value){
                    //targetNode是parent节点的左子树
                    parent.setLeftTreeNode(targetNode.getRightTreeNode());
                }else {
                    //targetNode是parent节点的右子树
                    parent.setRightTreeNode(targetNode.getRightTreeNode());
                }
            }
        }
	}
	/**
     * 查找要删除的节点
     * @param node
     * @param value
     * @return
     */
	//找到要删除的节点
	public TreeNode search(TreeNode node,int value) {
		if(value==node.getValue()) {
			return node;
		}else if(value<node.getValue()) {
			if(node.getLeftTreeNode()==null) {
				return null;
			}
			return search(node.getLeftTreeNode(), value);
		}else {
			if(node.getRightTreeNode()==null) {
				return null;
			}
			return search(node.getRightTreeNode(), value);
		}
	}
	/**
     * 找到要删除节点的父节点
     * @param node
     * @param value
     * @return
     */
	public TreeNode SearchParent(TreeNode node,int value) {
		if(node.getLeftTreeNode()!=null&&node.getLeftTreeNode().getValue()==value||
          (node.getRightTreeNode()!=null && node.getRightTreeNode().getValue() == value)) {
			return node;
		}else {
			if(node.getLeftTreeNode()!=null&&value<node.getValue()) {
				return SearchParent(node.getLeftTreeNode(), value);
			}else if(node.getRightTreeNode()!=null&&value>node.getValue()) {
				return SearchParent(node.getRightTreeNode(), value);
			}else {
				return null;
			}
		}
	}
	/**
     * 右子树的最小值
     * @param node
     * @return
     */
	public int delRightTreeMin(TreeNode node) {
		//定义指针
		TreeNode current=node;
		while(current.getLeftTreeNode()!=null) {
			current=current.getLeftTreeNode();
		}
		delNode(root, current.getValue());
		return current.getValue();
	}

Supongo que te gusta

Origin blog.csdn.net/qq_54247497/article/details/131539270
Recomendado
Clasificación