二叉排序数的创建不难,本文采用了递归和非递归两种方法创建。
删除基本上用的是非递归,在删除有两颗字树的节点时,使用了递归删除了要删除节点的右子树的最小节点。
删除思路如下:
1、删除只有一个根节点的直接设为null
2、删除叶子节点:需要寻找到父节点,通过父节点直接删除,否则会出现空指针
3、有一个子树的节点:寻找到父节点,将父节点下面需要删除的子节点变成需要删除的子节点的唯一子节点
4、有两个子树的节点:可以通过寻找需要删除的节点的左子节点中最大的或者要删除节点的右子树的最小节点的值来代替需要删除的节点,并删除代替的节点。
代码如下:
package binarysorttree;
public class BinarySortTreeDemo {
public static void main(String[] args) {
int[] arr = {7, 3, 10, 12, 5, 1, 9,13};
binarySortTree bst = new binarySortTree();
//循环的添加结点到二叉排序树
for(int i = 0; i< arr.length; i++) {
bst.add(new Node(arr[i]));
}
//中序遍历二叉排序树
System.out.println("中序遍历二叉排序树~");
bst.infixOrder(bst.getRoot()); // 1, 3, 5, 7, 9, 10, 12
// System.out.println("测试查找父节点和删除节点");
// System.out.println(bst.search(3));
// System.out.println(bst.searchParent(3));
System.out.println("测试删除");
bst.delNode(10);
bst.infixOrder(bst.getRoot());
}
}
class binarySortTree{
private Node root;
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
//删除节点
/**
* 分三种情况,删除的是叶子节点,直接通过父节点删除
* @param val
*/
public void delNode(int val) {
Node cur=search(val);
Node par=searchParent(val);
if(cur==null) {
System.out.println("没有该节点");
return;
}
//删除的只有一个根节点,父节点为null
if(cur==root&&cur.left==null&&cur.right==null) {
root=null;
return;
}
//删除的根节点只有一个子节点
if(cur==root) {
if(root.left!=null) {
root=root.left;
}else {
root=root.right;
}
return;
}
//要删除的是是叶子节点
if(cur.left==null&&cur.right==null) {
if(par.left==cur) {
par.left=null;
}else {
par.right=null;
}
return;
}
//左子树找最大的节点代替删除的,右子树找最小的节点代替删除的,任选其一
//要删除的是有两颗子树的节点
if(cur.left!=null&&cur.right!=null) {
Node tar=cur.right;
//找右子树最小的节点
while(tar.left!=null) {
tar=tar.left;
}
delNode(tar.value);//删除那个叶子节点
cur.value=tar.value;
return;
}
//删除的是由一颗子树的节点
if(cur.left!=null&&par.left==cur) {
par.left=cur.left;
}
if(cur.left!=null&&par.right==cur) {
par.right=cur.left;
}
if(cur.right!=null&&par.left==cur) {
par.left=cur.right;
}
if(cur.right!=null&&par.right==cur) {
par.right=cur.right;
}
}
//查找要删除的节点,非递归的方式
public Node search(int val) {
Node cur=root;
while(true) {
if(cur==null) {
System.out.println("树种没有该节点");
return null;
}
if(cur.value==val) {
return cur;
}
if(cur.left!=null&&val<cur.value) {
cur=cur.left;
}else if(cur.right!=null&&val>cur.value) {
cur=cur.right;
}else {
return null;
}
}
}
//查找要删除的父节点
public Node searchParent(int val) {
Node cur=root;
if(val==root.value) {
System.out.println("要删除的是根节点,无父节点");
return null;
}
while(true) {
if(cur.left!=null&&cur.left.value==val) {
return cur;
}
if(cur.right!=null&&cur.right.value==val) {
return cur;
}
if(cur.left!=null&&val<cur.value) {
cur=cur.left;
}else if(cur.right!=null&&val>cur.value){
cur=cur.right;
}else {
return null;
}
}
}
//递归创建节点,一个要放添加的节点,一个应该放根节点
public void add(Node node,Node curnode) {
if(root==null) {
root=node;
return;
}
if(node.value<curnode.value) {
if(curnode.left!=null) {
add(node,curnode.left);
}else {
curnode.left=node;
}
}else {
if(curnode.right!=null) {
add(node,curnode.right);
}else {
curnode.right=node;
}
}
}
//非递归创建
public void add(Node node) {
if(root==null) {
root=node;
return;
}
Node par=root;
while(true) {
if(node.value<par.value) {
if(par.left==null) {
par.left=node;
break;
}else {
par=par.left;
}
}else {
if(par.right==null) {
par.right=node;
break;
}else {
par=par.right;
}
}
}
}
//中序遍历
public void infixOrder(Node node) {
if(root==null) {
System.out.println("树为空,无法遍历");
return;
}
if(node.left!=null) {
infixOrder(node.left);
}
System.out.println(node);
if(node.right!=null) {
infixOrder(node.right);
}
}
}
class Node{
int value;
Node left;
Node right;
public Node(int value) {
super();
this.value = value;
}
@Override
public String toString() {
return "Node [value=" + value + "]";
}
}