/*
* 二叉树节点
*/
public class Node {
//数据项
public long data;
//左子节点
public Node leftChild;
//右子节点
public Node rightChild;
/**
* 构造方法
* @param data
*/
public Node(long data) {
this.data = data;
}
}
/*
* 二叉树
*/
public class Tree {
//根节点
public Node root;
/**
* 插入节点
* @param value
*/
public void insert(long value,String sValue) {
//封装节点
Node newNode = new Node(value);
//引用当前节点
Node current = root;
//引用父节点
Node parent;
//如果root为null,也就是第一插入的时候
if(root == null) {
root = newNode;
return;
} else {
while(true) {
//父节点指向当前节点
parent = current;
//如果当前指向的节点数据比插入的要大,则向左走
if(current.data > value) {
current = current.leftChild;
if(current == null) {
parent.leftChild = newNode;
return;
}
} else {
current = current.rightChild;
if(current == null) {
parent.rightChild = newNode;
return;
}
}
}
}
}
/**
* 查找节点
* @param value
*/
public Node find(long value) {
//引用当前节点,从根节点开始
Node current = root;
//循环,只要查找值不等于当前节点的数据项
while(current.data != value) {
//进行比较,比较查找值和当前节点的大小
if(current.data > value) {
current = current.leftChild;
} else {
current = current.rightChild;
}
//如果查找不到
if(current == null) {
return null;
}
}
return current;
}
/**
* 删除节点 删除节点需要父子两层指针
* @param value
*/
public boolean delete(long value) {
//引用当前节点,从根节点开始
Node current = root;
//应用当前节点的父节点
Node parent = root;
//是否为左节点
boolean isLeftChild = true;
while(current.data != value) {
parent = current;
//进行比较,比较查找值和当前节点的大小
if(current.data > value) {
current = current.leftChild;
isLeftChild = true;
} else {
current = current.rightChild;
isLeftChild = false;
}
//如果查找不到
if(current == null) {
return false;
}
}
//删除叶子节点,也就是该节点没有子节点
if(current.leftChild == null && current.rightChild == null) {
if(current == root) {
root = null;
} else if(isLeftChild) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
//current的右节点空,判断current是parrent的左孩子?右孩子?决定current的leftchild插入位置
} else if(current.rightChild == null) {
if(current == root) {
root = current.leftChild;
}else if(isLeftChild) {
parent.leftChild = current.leftChild;
} else {
//是右节点,比parent节点要大
parent.rightChild = current.leftChild;
}
//current只有右孩子的情况,其次判断current是parent的左右孩子,判断插入parent的位置
} else if(current.leftChild == null) {
if(current == root) {
root = current.rightChild;
} else if(isLeftChild) {//current是parent的左孩子
parent.leftChild = current.rightChild;
} else {//current是parent的右孩子
parent.rightChild = current.rightChild;
}
} else {//current既有左孩子,也有右孩子
Node successor = getSuccessor(current);
// 先处理删除节点的父
if(current == root) {
root = successor;
} else if(isLeftChild) {
parent.leftChild = successor;
} else{
parent.rightChild = successor;
}
// 处理删除节点的左节点
successor.leftChild = current.leftChild;
}
return true;
}
public Node getSuccessor(Node delNode) {
Node successor = delNode;
Node successorParent = delNode;
Node current = delNode.rightChild;
//寻找右子树的最左侧节点,比被删除节点稍微大一点
while(current != null) {
successorParent = successor;
successor = current;
current = current.leftChild; // 删除节点的右子树的最左侧孩子节点
}
//被删除的右孩子,不等于找到的最左侧节点,successor就是右子树的最左侧孩子,successorParent是父节点
//不等于就是找到了,
if(successor != delNode.rightChild) {
//将最左节点的右节点给父节点是左,比较小,所以放再left
successorParent.leftChild = successor.rightChild;
// 直接放到位置了
successor.rightChild = delNode.rightChild;
}
return successor;
}
/**
* 前序遍历
*/
public void frontOrder(Node localNode) {
if(localNode != null) {
//访问根节点
System.out.println(localNode.data + " ");
//前序遍历左子树
frontOrder(localNode.leftChild);
//前序遍历右子树
frontOrder(localNode.rightChild);
}
}
/**
* 中序遍历
*/
public void inOrder(Node localNode) {
if(localNode != null) {
//中序遍历左子树
inOrder(localNode.leftChild);
//访问根节点
System.out.println(localNode.data + " ");
//中旬遍历右子树
inOrder(localNode.rightChild);
}
}
/**
* 后序遍历
*/
public void afterOrder(Node localNode) {
if(localNode != null) {
//后序遍历左子树
afterOrder(localNode.leftChild);
//后序遍历右子树
afterOrder(localNode.rightChild);
//访问根节点
System.out.println(localNode.data + " " );
}
}
}