二叉排序树(查找树,搜索树)或者是一颗空树,或者是一颗具有如下性质的树:
1)若左子树不为空,那么左子树上面的所有节点的关键字值都比根节点的关键字值小
2)若右子树不为空,那么右子树上面的所有节点的关键字值都比根节点的关键字值大
3)左右子树都为二叉树
4)没有重复值(这一点在实际中可以忽略)
public class SearchBinaryTree {
//根节点
public TreeNode root;
/**
* 添加节点
*/
public TreeNode put(int data) {
TreeNode newNode = new TreeNode(data);
if (root == null) {
root = newNode;
return newNode;
}
TreeNode treeNode = root;
TreeNode parent = null;
while (treeNode != null) {
parent = treeNode;
if (data < treeNode.data) {
treeNode = treeNode.leftChild;
} else if (data > treeNode.data) {
treeNode = treeNode.rightChild;
} else {//相等情况不考虑 不插入
return treeNode;
}
}
newNode.parent = parent;
if (data < parent.data) {
parent.leftChild = newNode;
} else {
parent.rightChild = newNode;
}
return newNode;
}
/**
* 查找节点
*/
public TreeNode search(int data) {
if (root == null) {
return null;
}
TreeNode node = root;
while (node != null) {
if (data < node.data) {
node = node.leftChild;
} else if (data > node.data) {
node = node.rightChild;
} else {
return node;
}
}
return null;
}
/**
* 删除节点
*/
public void deleteNode(TreeNode node) {
if (node == null) {
throw new NoSuchElementException();
} else {
//先得到父亲
TreeNode parent = node.parent;
//1.是叶子
if (node.leftChild == null && node.rightChild == null) {
//特别情况 1.树上只有一个节点 或者空树
if (parent == null) {
root = null;
} else if (parent.leftChild == node) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
node.parent = null;
} else if (node.leftChild != null && node.rightChild == null) {
//只有左孩子
if (parent==null){//是根节点
node.leftChild.parent=null;
root=node.leftChild;
}else {
if (node==parent.leftChild){//要删除的节点在父亲左边
parent.leftChild=node.leftChild;
}else {//要删除节点在父亲右边
parent.rightChild=parent.leftChild;
}
node.leftChild.parent=parent;
}
node.parent=null;
node.leftChild=null;
} else if (node.leftChild == null && node.rightChild != null) {
//只有右孩子
if (parent==null){//是根节点
node.rightChild.parent=null;
root=node.rightChild;
}else {
node.rightChild.parent=parent;
if (node==parent.leftChild){//要删除的节点在父亲左边
parent.leftChild=node.rightChild;
}else {//要删除节点在父亲右边
parent.rightChild=node.rightChild;
}
}
node.parent=null;
node.rightChild=null;
} else {//有左右两个孩子
if (node.rightChild.leftChild==null){//如果右子树的左子树为空 就直接补上右子树
node.rightChild.leftChild=node.leftChild;
node.leftChild.parent=node.rightChild;
if (parent==null){
root=node.rightChild;
}else {
if (parent.leftChild==node){
parent.leftChild=node.rightChild;
node.rightChild.parent=parent;
}else {
parent.rightChild=node.rightChild;
node.rightChild.parent=parent;
}
}
}else {//否则就补上右子树的左子树上最小的一个
TreeNode leftNode=getMinLeftTreeNode(node.rightChild);
leftNode.leftChild=node.leftChild;
node.leftChild.parent=leftNode;
if (parent==null){
root=node.rightChild;
}else {
if (parent.leftChild==node){
parent.leftChild=node.rightChild;
node.rightChild.parent=parent;
}else {
parent.rightChild=node.rightChild;
node.rightChild.parent=parent;
}
}
}
node.parent=null;
node.rightChild=null;
node.leftChild=null;
}
}
}
private TreeNode getMinLeftTreeNode(TreeNode node) {
TreeNode curRoot=null;
if (node==null){
return null;
}else {
curRoot=node;
while (curRoot.leftChild!=null){
curRoot=curRoot.leftChild;
}
}
return curRoot;
}
/**
* 中序遍历
*/
public void midOrderTraverse(TreeNode root) {
if (root == null) {
return;
}
//LDR
midOrderTraverse(root.leftChild);
System.out.print(root.data + " ");
midOrderTraverse(root.rightChild);
}
public static class TreeNode {
int data;
TreeNode leftChild;
TreeNode rightChild;
TreeNode parent;
public TreeNode(int data) {
this.data = data;
this.leftChild = null;
this.rightChild = null;
this.parent = null;
}
}
}
测试结果
/*
5
2 8
1 4 6 9
3 7
*/
@Test
public void testBinaryTree(){
int[] array={5,2,8,6,8,5,9,4,1,7,3,9};
SearchBinaryTree searchBinaryTree=new SearchBinaryTree();
for (int i:array){
searchBinaryTree.put(i);
}
searchBinaryTree.midOrderTraverse(searchBinaryTree.root);
System.out.println();
System.out.println(searchBinaryTree.search(8).data);
SearchBinaryTree.TreeNode node=searchBinaryTree.search(5);
searchBinaryTree.deleteNode(node);
System.out.println();
searchBinaryTree.midOrderTraverse(searchBinaryTree.root);
}
打印结果看是正确的
1 2 3 4 5 6 7 8 9
8
1 2 3 4 6 7 8 9