查询的效率高于链表。
排序规则举例:如1,2,3,5,7,如果有相同的数可以放在左子节点或右字节点上。
二叉排序树如果使用中序遍历肯定是关键码值由小到大递增的。
在删除某结点的时候,可以让左子节点替代自己。
实现方法,包括查找、删除、添加
public class SortNode {
private int value;
private SortNode left;
private SortNode right;
public SortNode(int value) {
this.value=value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public SortNode getLeft() {
return left;
}
public void setLeft(SortNode left) {
this.left = left;
}
public SortNode getRight() {
return right;
}
public void setRight(SortNode right) {
this.right = right;
}
@Override
public String toString() {
return "SortNode [value=" + value + "]";
}
//添加新的结点
public void add(SortNode node) {
if(node==null) {
return;
}
/*
* 如果比它小,就往左放,如果比它大,就往右放。
*/
if(this.value>node.value) {
if (this.left==null) {
this.left=node;
}else {
this.left.add(node);
}
}
if (this.value<=node.value) {
if (this.right==null) {
this.right=node;
}else {
this.right.add(node);
}
}
}
//遍历使用中序遍历,在顺序二叉树中,就会按照关键码值大小顺序排列。
public void midList() {
if (this.left!=null) {
this.left.midList();
}
System.out.println(this);
if (this.right!=null) {
this.right.midList();
}
}
//查询节点的方法,按照关键码值找。在顺序二叉树中,小于就往左边找,大于就往右边找
public SortNode secNode(int value) {
if (this.value==value) {
return this;
}else if(this.value<value) {
if (this.left==null) {
return null;
}else {
return this.left.secNode(value);
}
}else {
if (this.right==null) {
return null;
}else {
return this.right.secNode(value);
}
}
}
//查询节点的父节点,为删除准备
public SortNode secFaNode(int value) {
if (((this.left!=null)&&(this.left.value==value))||((this.right!=null)&&(this.right.value==value))) {
return this;
}else if((this.left!=null)&&(this.value<value)) {
return this.left.secFaNode(value);
}else if ((this.right!=null)&&(this.value>value)) {
return this.right.secFaNode(value);
}else {
return null;
}
}
}
public class SortBinaryTree {
private SortNode root;
public SortBinaryTree(SortNode root) {
this.root=root;
}
public SortNode getRoot() {
return root;
}
//定义两个与结点方法相关的查找方法
public SortNode secNode(int value) {
if (root==null) {
return null;
}else {
return root.secNode(value);
}
}
public SortNode secFaNode(int Value) {
if (root==null) {
return null;
}else{
return root.secFaNode(Value);
}
}
//遍历方法
public void midList() {
if(root==null) {
return;
}else {
root.midList();
}
}
//添加结点方法
public void add(SortNode node) {
if (root==null) {
return;
}else {
root.add(node);
}
}
//找到右子树最小值
public SortNode findRightMin(SortNode node) {
if(node.getRight()==null) {
return node;
}else {
node=node.getRight();
while(node.getLeft()!=null) {
node=node.getLeft();
}
return node;
}
}
/*
* 如果删除节点没有子节点,直接删除
* 如果有一个子树,直接让其替代自己
* 如果有两个子树,让左子树中最小的或右子树中最大的替代自己
*/
public void delNode(int value) {
if (root==null) {
return;
}else {
SortNode target=secNode(value);
//因为root没有父节点,单独讨论
if(root==target) {
root=null;return;
}
if (target==null) {
return;
}else if((target.getRight()==null)&&(target.getLeft()==null)) {
//要删除的结点没有子结点
//现在判断要删除的结点是它父节点的左节点还是右结点
SortNode faNode=secFaNode(value);
if (faNode.getLeft()==target) {
faNode.setLeft(null);
}else {
faNode.setRight(null);
}
//有一个结点的情况,分左右
}else if((target.getLeft()!=null)&&target.getRight()==null) {
SortNode faNode=secFaNode(value);
if (faNode.getLeft()==target) {
faNode.setLeft(target.getLeft());
}else {
faNode.setRight(target.getLeft());
}
}else if((target.getLeft()==null)&&target.getRight()!=null) {
SortNode faNode=secFaNode(value);
if (faNode.getLeft()==target) {
faNode.setLeft(target.getRight());
}else {
faNode.setRight(target.getRight());
}
}else {
//两个子树都有,找到右边最小的,把它放到被删结点位置上,再把它删了
SortNode minRight=findRightMin(target);
target.setValue(minRight.getValue());
secFaNode(minRight.getValue()).setLeft(null);
}
}
}
}