性质:
1.对于树中的每一个节点X,它的左子树中的所有项的值均小于X的项,右子树中的所有项的值均大于X的项。
2.由于树的递归定义,通常都是递归地编写这些操作。因为树的平均深度为O(logN),所以一般不需要担心栈空间被用尽
3.二叉搜索树要求所有的项都能被排序,所以我们通过实现Compareable这个接口来表示这个性质。
节点的声明:
BSTNode类像链表类中的节点类一样,是一个嵌套类:
private class BSTNode<T extends Comparable<T>> {
T element;
BSTNode<T> left;
BSTNode<T> right;
BSTNode<T> parent;
int height;
public BSTNode(T element) {
this(element, null, null, null);
}
public BSTNode(T element, BSTNode<T> left, BSTNode<T> right, BSTNode<T> parent) {
this.element = element;
this.left = left;
this.right = right;
this.parent = parent;
}
public T getElement() {
return element;
}
}
代码实现:
下面是BinarySearchTree类架构,其中唯一的数据域是对根结点的引用
public class BinarySearchTree<T extends Comparable<T>> {
/**
* 根节点
*/
private BSTNode<T> mRoot;
/**
* 数值最大的节点
*/
private BSTNode<T> maxRoot;
/**
* 数值最小的节点
*/
private BSTNode<T> minRoot;
/**
* 是否包含节点
*/
private boolean isContain = false;
private class BSTNode<T extends Comparable<T>> {
T element;
BSTNode<T> left;
BSTNode<T> right;
int height;
public BSTNode(T element) {
this(element, null, null);
}
public BSTNode(T element, BSTNode<T> left, BSTNode<T> right) {
this.element = element;
this.left = left;
this.right = right;
}
public T getElement() {
return element;
}
}
/**
* 插入节点
*/
public void insert(T element) {mRoot = insert(element, mRoot);}
/**
* 删除节点
*/
public void remove(T element) {mRoot = remove(element, mRoot);}
/**
* 中序遍历
*/
public void printTree() {
if (isEmpty()) {
System.out.println("Empty tree");
} else {
printTree(mRoot);
}
}
private void printTree(BSTNode<T> mRoot) {}
/**
* 还可以优化,专门写一个removeMin方法来删除具有子节点的节点
* 有时间再写吧
* @param element
* @param mRoot
* @return BSTNode<T>
*/
private BSTNode<T> remove(T element, BSTNode<T> mRoot) {}
/**
* 置空
*/
public void makeEmpty() {mRoot = null;}
/**
* 判断二叉树是否为空
*/
public boolean isEmpty() {return mRoot == null;}
/**
* 是否包含节点
*/
public boolean contain(T element) {
setContain();
return contain(element, mRoot);
}
/**
* 查询最小节点
*/
public T findMin() {return findMin(mRoot).element;}
/**
* 查询最大节点
*/
public T findMax() { return findMax(mRoot).element;}
private BSTNode<T> findMax(BSTNode<T> mRoot) { }
private BSTNode<T> findMin(BSTNode<T> mRoot) { }
private BSTNode<T> insert(T element, BSTNode<T> mRoot) {}
private boolean contain(T element, BSTNode<T> mRoot) {}
public int height(){}
private int height(BSTNode<T> mRoot){}
public void setContain() { isContain = false; }
}
insert代码
private BSTNode<T> insert(T element, BSTNode<T> mRoot) {
if (mRoot == null) {
return new BSTNode<>(element, null, null);
}
int compareResult = element.compareTo(mRoot.element);
if (compareResult < 0) {
mRoot.left = insert(element, mRoot.left);
} else if (compareResult > 0) {
mRoot.right = insert(element, mRoot.right);
}
return mRoot;
}
remove代码
private BSTNode<T> remove(T element, BSTNode<T> mRoot) {
if (mRoot == null) {
return mRoot;
}
int compareResult = element.compareTo(mRoot.element);
if (compareResult > 0) {
remove(element, mRoot.right);
} else if (compareResult < 0) {
remove(element, mRoot.left);
} else if (mRoot.left != null && mRoot != null) {
mRoot.element = findMin(mRoot.right).element;
mRoot.right = remove(mRoot.element, mRoot.right);
} else {
mRoot = (mRoot.left != null) ? mRoot.left : mRoot.right;
}
return mRoot;
}
contain代码
这块儿else里直接返回true会报错,纠结了半天还是加了一个全局变量,在每次contain的时候都置为失败,回头想想还有什么办法吧
private boolean contain(T element, BSTNode<T> mRoot) {
if (mRoot == null) {
return false;
}
int compareResult = element.compareTo(mRoot.element);
if (compareResult > 0) {
contain(element, mRoot.right);
} else if (compareResult < 0) {
contain(element, mRoot.left);
} else {
isContain = true;
}
return isContain;
}
public void setContain() { isContain = false; }
findMax代码
private BSTNode<T> findMax(BSTNode<T> mRoot) {
if (mRoot.right != null) {
findMax(mRoot.right);
}else{
maxRoot = mRoot;
}
return maxRoot;
}
findMin代码
private BSTNode<T> findMin(BSTNode<T> mRoot) {
if (mRoot.left != null) {
findMin(mRoot.left);
}else{
minRoot = mRoot;
}
return minRoot;
}
printTree代码
private void printTree(BSTNode<T> mRoot) {
if (mRoot != null) {
printTree(mRoot.left);
System.out.print("[" + mRoot.element + "]");
printTree(mRoot.right);
}
}
测试结果:
我是按照前序遍历输入的4,2,1,3,6,5,7,自己构造了一个AVL树,下面是输出结果
二叉树的最小值为:1
二叉树的最大值为:7
二叉树属性是否包含5:true
二叉树属性是否包含10:false
2
[1][2][3][4][5][6][7]
先做个笔记,二叉树的图以后慢慢补吧