1、二叉排序数介绍
回到最初的需求,既然我们已经有了数组和链表这两种数据结构,为什么还需要树这种结构呢?
二叉树的删除,比较复杂
代码实现:
package com.sorttree; public class BinarySortTreeDemo { } //定义二叉树类 class BinarySortTree { private Node root; public void setRoot(Node root) { this.root = root; } //添加节点的方法 public void add(Node node) { if (root == null) { root = node; } else { root.add(node); } } //查找目标值的节点 public Node search(int value) { if (root == null) { return null; } else { return root.search(value); } } //查找目标值的父节点 public Node searchParent(int value) { if (root == null) { return null; } else { return root.searchParent(value); } } //前序遍历 public void preOrder() { if (this.root != null) { this.root.postOrder(); } else { System.out.println("二叉树为空,无法遍历"); } } //中序遍历 public void infixOrder() { if (this.root != null) { this.root.infixOrder(); } else { System.out.println("二叉树为空,无法遍历"); } } //后序遍历 public void postOrder() { if (this.root != null) { this.root.postOrder(); } else { System.out.println("二叉树为空,无法遍历"); } } //删除节点,比较复杂 public void delNode(int value) { if (root == null) { return; } else { //找到要删除的节点,targetNode Node targetNode = search(value); if (targetNode == null) { //没有找到该节点 return; } //如果发现这个二叉树只有一个节点,即根节点root if (root.left == null && root.right == null) { root = null; return; } //找到目标值的父节点 Node parentNode = searchParent(value); //1.如果要删除的节点是叶子节点 if (targetNode.left == null && targetNode.right == null) { //这个时候要判断该节点是左子节点还是右子节点 if (parentNode.left != null && parentNode.left.value == value) { parentNode.left = null; } else if (parentNode.right != null && parentNode.right.value == value) { parentNode.right = null; } } else if (targetNode.left != null && targetNode.right != null) { //这一步是删除有两颗子树的节点 int minVal = delRightTreeMin(targetNode.right); targetNode.value = minVal; } else { //删除只有一颗子树的节点 if (targetNode.left != null) {//要删除的节点有左子节点 if (parentNode != null) { if (parentNode.left.value == value) { parentNode.left = targetNode.left; } else { parentNode.right = targetNode.left; } } else { root = targetNode.left; } } else {//要删除的节点有右子节点 if (parentNode != null) { if (parentNode.left.value == value) { parentNode.left = targetNode.right; } else { parentNode.right = targetNode.right; } } else { root = targetNode.right; } } } } } //以当前node节点为传入的根节点,寻找返回该范围内的最小节点的值,并删除之 //假象当前的树都是升序树 public int delRightTreeMin(Node node) { Node target = node; while (target.left != null) { target = target.left; } delNode(target.value); return target.value; } } class Node { public int value; public Node left; public Node right; public Node(int value) { this.value = value; } @Override public String toString() { return "Node{" + "value=" + value + '}'; } //二叉排序树和普通二叉树的最大不同,在于添加数据的时候就将数据有序了,也是核心 public void add(Node node) { if (node == null) { return; } if (this.value > node.value) { if (this.left == null) { this.left = node; } else { this.left.add(node); } } else { if (this.right == null) { this.right = node; } else { this.right.add(node); } } } //前序遍历 public void preOrder() { System.out.println(this); if (this.left != null) { this.left.preOrder(); } if (this.right != null) { this.right.preOrder(); } } //中序遍历 public void infixOrder() { if (this.left != null) { this.infixOrder(); } System.out.println(this); if (this.right != null) { this.right.infixOrder(); } } //后序遍历 public void postOrder() { if (this.left != null) { this.left.postOrder(); } if (this.right != null) { this.right.postOrder(); } System.out.println(this); } //查找目标值的节点 public Node search(int value) { if (this.value == value) { return this; } else if (this.value > value) { if (this.left == null) { return null; } return this.left.search(value); } else { if (this.right == null) { return null; } return this.right.search(value); } } //查找目标值的父节点 public Node searchParent(int value) { if ((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value)) { return this; } else { if (this.value > value && this.left != null) { return this.left.search(value); } else if (this.value < value && this.right != null) { return this.right.search(value); } else { return null; } } } }