二叉查找树由节点构成,每个结构包含数值元素,左子树(指向左边相连的节点的指针),右子树(指向右边相连的节点的指针),父节点(指向父节点的指针)
public class BinaryNode {
private int data;
private BinaryNode left=null;
private BinaryNode right=null;
private BinaryNode parent=null;
public BinaryNode getParent() {
return parent;
}
public void setParent(BinaryNode parent) {
this.parent = parent;
}
public BinaryNode(int data){
this.data=data;
}
public BinaryNode(){
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public BinaryNode getLeft() {
return left;
}
public void setLeft(BinaryNode left) {
this.left = left;
}
public BinaryNode getRight() {
return right;
}
public void setRight(BinaryNode right) {
this.right = right;
}
}
二叉查找树的特点是每个节点的值都大于它左子树的数值,而小于它又子树的数值,不能有重复元素。第一个添加的元素即为根节点。
//构造二叉查找树
public class BinaryTree {
private BinaryNode root;
public BinaryTree(int num) {
root = new BinaryNode(num);
}
/*
添加节点,如果是第一次添加,则该节点为root节点,所有节点中只有root节点的父节点为null
添加的方法是进行递归比较,比当前节点值小的往左子树上靠,比当前节点值大的往右子树上靠,
如果正好和本节点值相等,则舍弃(因为二叉查找树不能有重复元素)
*/
public void insert(int num) {
BinaryNode node = root;
while (node != null) {
if (num == node.getData()) {
return;
} else if (num < node.getData()) {
if (node.getLeft() == null) {
BinaryNode new_node = new BinaryNode(num);
node.setLeft(new_node);
new_node.setParent(node);
return;
} else {
node = node.getLeft();
continue;
}
} else {
if (node.getRight() == null) {
BinaryNode new_node = new BinaryNode(num);
node.setRight(new_node);
new_node.setParent(node);
return;
} else {
node = node.getRight();
continue;
}
}
}
}
//删除节点的入口,递归调用重载的delete函数
public void delete(int num) {
delete(num, root);
}
/*
删除策略:1.如果是空树,返回;
2.如果要删除的数值小于当前节点的数值,在左节点上递归删除,如果要删除的数值大于当前节点的数值,在右节点上递归删除;
3.如果要删除的数值等于当前节点的数值,分下列情形分别处理:
a.当前节点既有左子树又有右子树,那么找到右子树中最小的那个节点(即右子树上最左的那个节点,即为RightMin节点),
将当前节点的数值设置为RightMin节点的数值,然后重新调用delete函数删除RightMin节点;
b.如果只有左子树,则删掉该节点,直接用左子树代替之。注意要重新设置parent,如果删除了root节点,需要重新指定root;
c.如果只有右子树,则删掉该节点,直接用右子树代替之。注意要重新设置parent,如果删除了root节点,需要重新指定root;
d.如果既没有左子树也没有右子树,直接删除之;
*/
private void delete(int num, BinaryNode node) {
if (node == null)
return;
if (num > node.getData()) {
delete(num, node.getRight());
} else if (num < node.getData()) {
delete(num, node.getLeft());
} else {
if (node.getLeft() != null && node.getRight() != null) {
int min = findMin(node.getRight());
delete(min, node.getRight());
node.setData(min);
} else {
BinaryNode tt = (node.getLeft() != null) ? node.getLeft()
: node.getRight();
BinaryNode p = node.getParent();
if (p == null) {
root = tt;
if (root != null)
root.setParent(null);
} else {
if (p.getData() > node.getData())
p.setLeft(tt);
else
p.setRight(tt);
if(tt!=null)
tt.setParent(p);
}
}
}
}
//查找最小节点的入口
public int findMin() {
return findMin(root);
}
//递归查找,知道找到最左的那个节点
private int findMin(BinaryNode node) {
BinaryNode new_node = node;
while (new_node.getLeft() != null)
new_node = new_node.getLeft();
return new_node.getData();
}
}