二叉排序树
1.背景
面试中经常问到关于树的结构
2.代码实现
package com.ldp.structure.demo07BST; import org.junit.Test; /** * @create 05/03 11:18 * @description <p> * 二叉排序树 * </p> */ public class Test01 { /** * 二叉排序树,添加测试 */ @Test public void test01() { int[] array = {7, 3, 10, 12, 5, 1, 9}; BstTree bstTree = new BstTree(); // 添加到二叉树 for (int i : array) { bstTree.add(new Node(i)); } // 中序遍历 // bstTree.middleList(); // 目标节点查找 //int value = 70; //System.out.println("getTargetNode=>" + bstTree.getTargetNode(value)); // 目标节点父节点查找 // System.out.println("getTargetNodeParent=>" + bstTree.getTargetNodeParent(value)); // 待删除的节点有零个叶子节点(本身是叶子节点)(1,5,9,12) // bstTree.delete(12); // 待删除的节点有一个叶子节点 //bstTree.add(new Node(11)); // bstTree.delete(12); //待删除的节点有两个叶子节点 bstTree.delete(3); bstTree.middleList(); } /** * 任意删除测试 */ @Test public void test02() { int[] array = {7, 3, 10, 12, 5, 1, 9}; BstTree bstTree = new BstTree(); for (int i : array) { bstTree.add(new Node(i)); } bstTree.delete(1); bstTree.delete(3); bstTree.delete(12); bstTree.delete(5); bstTree.delete(7); bstTree.delete(9); bstTree.delete(10); bstTree.middleList(); } } class BstTree { Node root; /** * 添加节点 * * @param node */ public void add(Node node) { if (root == null) { root = node; } else { root.add(node); } } /** * 删除节点 * * @param value */ public void delete(Integer value) { Node targetNode = getTargetNode(value); if (targetNode == null) { System.out.println("该节点不存在:value=" + value); return; } Node targetNodeParent = getTargetNodeParent(value); // 1.待删除的节点有零个叶子节点(本身是叶子节点) if (targetNode.leftNode == null && targetNode.rightNode == null) { deleteZero(targetNodeParent, value); System.out.println("节点删除成功:value=" + value); } else if (targetNode.leftNode != null && targetNode.rightNode != null) { // 3.待删除的节点有两个叶子节点 deleteTwo(targetNode); System.out.println("节点删除成功:value=" + value); } else { // 2.待删除的节点有一个叶子节点 deleteOne(targetNodeParent, targetNode, value); System.out.println("节点删除成功:value=" + value); } } /** * 待删除的节点有零个叶子节点(本身是叶子节点) * 1.找到待删除的节点 targetNode; * 2.找到targetNode的父节点 parentNode; * 3.判定targetNode是parentNode的左节点还是右节点 * 如果targetNode是parentNode的左节点:parentNode.leftNode=null; * 如果targetNode是parentNode的右节点:parentNode.rightNode=null; */ private void deleteZero(Node nodeParent, Integer value) { if (nodeParent == null) { root = null; return; } if (nodeParent.leftNode.value == value) { nodeParent.leftNode = null; } else { nodeParent.rightNode = null; } } /** * 待删除的节点有一个叶子节点 * 1.找到待删除的节点 targetNode; * 2.找到targetNode的父节点 parentNode; * 3.判定targetNode是parentNode的左节点还是右节点 * 如果targetNode是parentNode的左节点: * 且targetNode的叶子节点是左节点:parentNode.leftNode=targetNode.leftNode * 且targetNode的叶子节点是右节点:parentNode.leftNode=targetNode.rightNode * 如果targetNode是parentNode的右节点: * 且targetNode的叶子节点是左节点:parentNode.rightNode=targetNode.leftNode * 且targetNode的叶子节点是右节点:parentNode.rightNode=targetNode.rightNode */ private void deleteOne(Node nodeParent, Node targetNode, Integer value) { Node tempNode; if (targetNode.leftNode != null) {// targetNode的叶子节点是左节点 tempNode = targetNode.leftNode; } else { tempNode = targetNode.rightNode; } // 如果父节点为空 if (nodeParent == null) { root = tempNode; return; } if (nodeParent.leftNode != null && nodeParent.leftNode.value == value) {// 如果targetNode是parentNode的左节点 nodeParent.leftNode = tempNode; } else { nodeParent.rightNode = tempNode; } } /** * 待删除的节点有两个叶子节点 * 1.找到待删除的节点 targetNode; * 2.targetNode的右节点开始找,找到最小节点 * 3.用一个临时节点minNode保存 * 4.删除最小节点 * 5.targetNode.value=minNode.value * * @param targetNode */ private void deleteTwo(Node targetNode) { Node minNodeParent = targetNode; Node minNode = targetNode.rightNode; if (targetNode.rightNode.leftNode == null) { // 如果股目标节点的右节点没有左子节点,则右节点是最小节点 minNodeParent.rightNode = null; targetNode.value = minNode.value; } else {// 如果股目标节点的右节点有左子节点,则一直往最左边找,最后一个左节点是最小节点 while (true) { if (minNode.leftNode != null) { minNodeParent = minNode; minNode = minNode.leftNode; } else { break; } } minNodeParent.leftNode = null; targetNode.value = minNode.value; } } /** * 根据value找到目标节点 * * @param value * @return */ public Node getTargetNode(Integer value) { Node tempNode = root; while (tempNode != null) { if (tempNode.value.equals(value)) {// 已找到 break; } else if (value < tempNode.value) { tempNode = tempNode.leftNode; } else { tempNode = tempNode.rightNode; } } return tempNode; } /** * 根据value找到目标节点的父节点 * * @param value * @return */ public Node getTargetNodeParent(Integer value) { if (this.root.value.equals(value)) { System.out.println("该节点没有父节点....."); return null; } Node parentNode = null; Node tempNode = root; while (tempNode != null) { if (tempNode.value.equals(value)) {// 已找到 break; } else if (value < tempNode.value) { parentNode = tempNode; tempNode = tempNode.leftNode; } else { parentNode = tempNode; tempNode = tempNode.rightNode; } } if (tempNode == null) { return null; } return parentNode; } public void middleList() { if (root == null) { System.out.println("节点为空..."); } else { root.middleList(); } } } class Node { Integer value; Node leftNode; Node rightNode; public Node(Integer value) { this.value = value; } /** * 添加一个节点 * * @param node */ public void add(Node node) { if (node.value < this.value) { // 放在左边 if (this.leftNode == null) { this.leftNode = node; } else { this.leftNode.add(node); } } else {// 放在右边 if (this.rightNode == null) { this.rightNode = node; } else { this.rightNode.add(node); } } } /** * 中序遍历 */ public void middleList() { if (this.leftNode != null) { this.leftNode.middleList(); } System.out.println(this); if (this.rightNode != null) { this.rightNode.middleList(); } } @Override public String toString() { return "Node{" + "value=" + value + '}'; } }