入门知识
二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。
添加
递归实现
在BinarySearchTree.java 中添加如下代码:
/** * * @Title: add * @Description:二叉查找树添加的方法 * @param: data * @return: void * @throws */public void add(Comparable data) {if(root == null) {root = new Node(data);}else {root.add(data);}}
在内部类 Node.java 中添加如下代码:
/** * @Title: add * @Description:添加方法 * 实现:调用 Comparable 接口的 compareTo 方法,比较对象大小 * 1、如果当前对象小于指定对象,返回负整数 * 2、如果当前对象等于指定对象,返回0 * 3、如果当前对象大于指定对象,返回正整数 * * 如果返回正整数,进左子树 * 如果返回负整数或0,进右子树 * @param: data * @return: void * @throws */public void add(Comparable data) {if(this.data.compareTo(data) > 0) {if(this.left==null) {this.left = new Node(data);}else {this.left.add(data);}}else if(this.data.compareTo(data) <= 0) {if(this.right == null) {this.right = new Node(data);}else {this.right.add(data);}}}
迭代实现
遍历
在BinarySearchTree.java类中添加如下代码:
** * * @Title: inFixOrder * @Description:中序遍历 * @param: * @return: void * @throwss */public void inFixOrder() {if(root == null) {System.out.println("树为空!");}else {root.inFixOrder();}}
在内部类Node.java中添加如下代码:
/** * @Title: inFixOrder * @Description:中序遍历 * @param: * @return: void * @throws */public void inFixOrder() {//先遍历左子树if(this.left!=null) {this.left.inFixOrder();}//打印数据System.out.println(this);//遍历右子树if(this.right!=null) {this.right.inFixOrder();}}
测试代码:
/** * All rights Reserved, Designed By https://www.tulingxueyuan.com/ * @Title: BinarySearchTreeDemo.java * @Package com.tuling.tree * @Description: * @author: 小白 * @Date 2019年12月7日 上午1:18:33 * @version V1.0 * @Copyright: */ package com.tuling.tree;/** * @ClassName BinarySearchTreeDemo * @Description * @Author 北京图灵学院 * @Date 2019年12月7日 上午1:18:33 */public class BinarySearchTreeDemo {/** * @Title: main * @Description: * @param: @param args * @return: void * @throws */public static void main(String[] args) {BinarySearchTree bst = new BinarySearchTree();bst.add(25);bst.add(43);bst.add(2);bst.add(765);bst.add(23);bst.add(1);bst.add(76);bst.inFixOrder();}}
运行效果:
查找和获取
在BinarySearchTree.java类中添加如下代码
/** * * @Title: bstSearch * @Description:查找 * @param: data * @param: * @return: Node * @throws */public Node bstSearch(Comparable data) {if(root.data.compareTo(data)==0) {return root;}else {return root.bstSearch(data);}}
在内部类Node.java中添加如下代码:
/** * @Title: bstSearch * @Description:查找 * @param: data * @param: * @return: Node * @throws */public Node bstSearch(Comparable data) {if(this.data.compareTo(data) == 0) {return this;}else if(this.data.compareTo(data)>0) {//如果要查找的对象小于当前对象,向左子树查找。if(this.left == null) {//如果左子树为空。return null;}//递归向左子树查找。return this.left.bstSearch(data);}else if(this.data.compareTo(data) <= 0) {//如果要查找的对象大于或等于当前对象,向右子树查找。if(this.right == null) {return null;}//递归向右子树查找return this.right.bstSearch(data);}return null;}
删除
删除功能代码如下:
/** * * @Title: del * @Description:删除 * @param: @param data * @param: @return * @return: boolean * @throws */public void del(Comparable data) {if(root == null) {return;}//先找到需要删除的节点Node delNode = bstSearch(data);//如果没有找到要删除的节点if(delNode==null) {return;}//找到要删除的节点的父节点Node parentNode = searchParent(delNode);//if(parentNode==null)return;//如果要删除的节点是叶节点if(delNode.left==null && delNode.right==null) {//判断 delNode 是父节点的左子树还是右子树if(parentNode.left!=null && parentNode.left.data.equals(delNode.data)) {parentNode.left = null;}else if(parentNode.right!=null && parentNode.right.data.equals(delNode.data)) {parentNode.right = null;}}else if(delNode.left!=null && delNode.right!=null) {//要删除的节点有两个子节点//获取后继节点的数据Comparable minNodeData = getRightTreeMin(delNode.right);//转移后继节点的值到当前要删除的节点delNode.data = minNodeData;}else {//删除只有一个子树的节点/* * 要删除的节点有左子树 */if(delNode.left!=null) {if(parentNode!=null) {//要删除的节点为父节点的左子树if(parentNode.left!=null && parentNode.left.data.compareTo(delNode.data) == 0) {parentNode.left = delNode.left;}else {//要删除的节点为父节点的右子树parentNode.right = delNode.left;}}else {//删除的是rootroot = delNode.left;}}else {//要删除的节点有右子树if(parentNode!=null) {//要删除的节点为父节点的左子树if(parentNode.left!=null && parentNode.left.data.compareTo(delNode.data) == 0) {parentNode.left = delNode.right;}else {//要删除的节点为父节点的右子树parentNode.right = delNode.right;}}else {//删除的是rootroot = delNode.right;}}}}
查找父节点功能代码如下:
/** * @Title: searchParent * @Description:查找要删除的节点的父节点 * @param: @param delNode * @param: @return * @return: Node * @throws */private Node searchParent(Node delNode) {if(root == null) {return null;}else {return this.root.searchParent(delNode);}}
内部类Node.java中的代码如下:
/** * @Title: searchParent * @Description:递归查找要删除的节点的父节点 * @param: @param delNode * @param: @return * @return: Node * @throws */public Node searchParent(Node delNode) {//如果当前节点就是要删除节点的父节点if(this.left!=null && this.left.data.compareTo(delNode.data)==0 || this.right!=null && this.right.data.compareTo(delNode.data) == 0) {return this;}else {//当前节点不是要删除节点的父节点,需要递归向下遍历查找。//如果当前对象的左子树不为空,并且要查找的对象小于当前对象,递归向左子树查找。if(this.left!=null && this.data.compareTo(delNode.data) > 0) {return this.left.searchParent(delNode);}else if(this.right!=null && this.data.compareTo(delNode.data) <= 0) {return this.right.searchParent(delNode);}else {//没有找到父节点return null;}}}
二叉查找树BinarySearchTree.java类完整代码如下:
/** * All rights Reserved, Designed By https://www.tulingxueyuan.com/ * @Title: BinarySearchTree.java * @Package com.tuling.tree * @Description: * @author: 小白 * @Date 2019年12月7日 上午12:46:43 * @version V1.0 * @Copyright: */ package com.tuling.tree;/** * @ClassName BinarySearchTree * @Description * @Author 北京图灵学院 * @Date 2019年12月7日 上午12:46:43 */public class BinarySearchTree {private Node root;/** * * @Title: add * @Description:二叉查找树添加的方法 * @param: data * @return: void * @throws */public void add(Comparable data) {if(root == null) {root = new Node(data);}else {root.add(data);}}/** * * @Title: inFixOrder * @Description:中序遍历 * @param: * @return: void * @throws */public void inFixOrder() {if(root == null) {System.out.println("树为空!");}else {root.inFixOrder();}}/** * * @Title: bstSearch * @Description:查找 * @param: data * @param: * @return: Node * @throws */public Node bstSearch(Comparable data) {if(root == null) {return null;}else {return this.root.bstSearch(data);}}/** * @Title: searchParent * @Description:查找要删除的节点的父节点 * @param: @param delNode * @param: @return * @return: Node * @throws */private Node searchParent(Node delNode) {if(root == null) {return null;}else {return this.root.searchParent(delNode);}}/** * * @Title: del * @Description:删除 * @param: @param data * @param: @return * @return: boolean * @throws */public void del(Comparable data) {if(root == null) {return;}//先找到需要删除的节点Node delNode = bstSearch(data);//如果没有找到要删除的节点if(delNode==null) {return;}//找到要删除的节点的父节点Node parentNode = searchParent(delNode);//if(parentNode==null)return;//如果要删除的节点是叶节点if(delNode.left==null && delNode.right==null) {//判断 delNode 是父节点的左子树还是右子树if(parentNode.left!=null && parentNode.left.data.equals(delNode.data)) {parentNode.left = null;}else if(parentNode.right!=null && parentNode.right.data.equals(delNode.data)) {parentNode.right = null;}}else if(delNode.left!=null && delNode.right!=null) {//要删除的节点有两个子节点//获取后继节点的数据Comparable minNodeData = getRightTreeMin(delNode.right);//转移后继节点的值到当前要删除的节点delNode.data = minNodeData;}else {//删除只有一个子树的节点/* * 要删除的节点有左子树 */if(delNode.left!=null) {if(parentNode!=null) {//要删除的节点为父节点的左子树if(parentNode.left!=null && parentNode.left.data.compareTo(delNode.data) == 0) {parentNode.left = delNode.left;}else {//要删除的节点为父节点的右子树parentNode.right = delNode.left;}}else {//删除的是rootroot = delNode.left;}}else {//要删除的节点有右子树if(parentNode!=null) {//要删除的节点为父节点的左子树if(parentNode.left!=null && parentNode.left.data.compareTo(delNode.data) == 0) {parentNode.left = delNode.right;}else {//要删除的节点为父节点的右子树parentNode.right = delNode.right;}}else {//删除的是rootroot = delNode.right;}}}}/** * @Title: getRightTreeMin * @Description:返回要删除的节点右子树的最小节点 * @param: @param delNode * @param: @return * @return: Node * @throws */private Comparable getRightTreeMin(Node delNode) {Node tempNode = delNode;//循环向左查找即可while(tempNode.left!=null) {tempNode = tempNode.left;}//循环结束,tempNode指向要删除节点右子树的最小节点。//删除最小节点del(tempNode.data);return tempNode.data;}/** * * @ClassName Node * @Description:二叉树的节点数据结构 * @Author 北京图灵学院 * @Date 2019年12月7日 上午1:46:33 */class Node{private Comparable data;private Node left;private Node right;/** * @Title: Node * @Description: * @param: * @throws */ public Node() {super();}/** * @Title: searchParent * @Description:递归查找要删除的节点的父节点 * @param: @param delNode * @param: @return * @return: Node * @throws */public Node searchParent(Node delNode) {//如果当前节点就是要删除节点的父节点if(this.left!=null && this.left.data.compareTo(delNode.data)==0 || this.right!=null && this.right.data.compareTo(delNode.data) == 0) {return this;}else {//当前节点不是要删除节点的父节点,需要递归向下遍历查找。//如果当前对象的左子树不为空,并且要查找的对象小于当前对象,递归向左子树查找。if(this.left!=null && this.data.compareTo(delNode.data) > 0) {return this.left.searchParent(delNode);}else if(this.right!=null && this.data.compareTo(delNode.data) <= 0) {return this.right.searchParent(delNode);}else {//没有找到父节点return null;}}}/** * @Title: bstSearch * @Description:查找 * @param: data * @param: * @return: Node * @throws */public Node bstSearch(Comparable data) {if(this.data.compareTo(data) == 0) {return this;}else if(this.data.compareTo(data)>0) {//如果要查找的对象小于当前对象,向左子树查找。if(this.left == null) {//如果左子树为空。return null;}//递归向左子树查找。return this.left.bstSearch(data);}else if(this.data.compareTo(data) <= 0) {//如果要查找的对象大于或等于当前对象,向右子树查找。if(this.right == null) {return null;}//递归向右子树查找return this.right.bstSearch(data);}return null;}/** * @Title: inFixOrder * @Description:中序遍历 * @param: * @return: void * @throws */public void inFixOrder() {//先遍历左子树if(this.left!=null) {this.left.inFixOrder();}//打印数据System.out.println(this);//遍历右子树if(this.right!=null) {this.right.inFixOrder();}}/** * @Title: add * @Description:添加方法 * 实现:调用 Comparable 接口的 compareTo 方法,比较对象大小 * 1、如果当前对象小于指定对象,返回负整数 * 2、如果当前对象等于指定对象,返回0 * 3、如果当前对象大于指定对象,返回正整数 * * 如果返回正整数,进左子树 * 如果返回负整数或0,进右子树 * @param: data * @return: void * @throws */public void add(Comparable data) {if(this.data.compareTo(data) > 0) {if(this.left==null) {this.left = new Node(data);}else {this.left.add(data);}}else if(this.data.compareTo(data) <= 0) {if(this.right == null) {this.right = new Node(data);}else {this.right.add(data);}}}/** * @Title: Node * @Description: * @param: @param data * @throws */ public Node(Comparable data) {super();this.data = data;}/****/@Overridepublic String toString() {return "Node [data=" + data + "]";}}}