BST.java |
Main.java |
BST.java
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
//定义二分搜索树的类
public class BST<E extends Comparable<E>> {//泛型要求是可以比较的
private class Node {//定义节点类
public E e;
public Node left, right;
public Node(E e) {
this.e = e;
left = null;
right = null;
}
}
private Node root;
private int size;
//二叉树构造函数
public BST(){
root = null;
size = 0;
}
//getsize
public int size(){
return size;
}
//判断二叉树是否为空
public boolean isEmpty(){
return size == 0;
}
// 向二分搜索树中添加新的元素e
public void add(E e){
if(root == null){
root = new Node(e);
size ++;
}
else
add(root, e);//调用函数add(Node node, E e)
}
// 向以node为根的二分搜索树中插入元素e,递归算法
/*private void add(Node node, E e){
if(e.equals(node.e))//如果元素e等于根节点的值
return;//提前退出函数
else if(e.compareTo(node.e) < 0 && node.left == null){
//如果元素e小于根节点的值且根节点的左子节点为空
node.left = new Node(e);//将e添加到左节点
size ++;
return;
}
else if(e.compareTo(node.e) > 0 && node.right == null){
//如果元素e大于根节点的值且根节点的右子节点为空
node.right = new Node(e);//将e添加到右节点
size ++;
return;
}
if(e.compareTo(node.e) < 0)
//如果e小于根节点且根节点的左子节点不为空
add(node.left, e);
else //e.compareTo(node.e) > 0
//如果e大于根节点且根节点的右子节点不为空
add(node.right, e);
}*/
//向以node为根的二分搜索树中插入元素e,递归算法
//返回插入新节点后二分搜索树的根
private Node add(Node node,E e) {
if(node==null) {
size++;
return new Node(e);
}
if(e.compareTo(node.e)<0) {
node.left=add(node.left,e);//因为空子树本身也是一颗二叉树,所以可以这样写
}
else if(e.compareTo(node.e)>0) {
node.right=add(node.right,e);
}
return node;
}
// 看二分搜索树中是否包含元素e
public boolean contains(E e){
return contains(root, e);
}
// 看以node为根的二分搜索树中是否包含元素e, 递归算法
private boolean contains(Node node, E e){
if(node == null)
return false;
if(e.compareTo(node.e) == 0)
return true;
else if(e.compareTo(node.e) < 0)
return contains(node.left, e);
else {//必须写成else不然会报错
return contains(node.right, e);
}
}
// 二分搜索树的前序遍历
public void preOrder(){
preOrder(root);
}
// 前序遍历以node为根的二分搜索树, 递归算法
private void preOrder(Node node){
if(node == null)
return;
System.out.println(node.e);//节点,左子树,右子树
preOrder(node.left);
preOrder(node.right);
}
// 二分搜索树的非递归前序遍历
public void preOrderNR(){//借助了系统栈
/*Stack stack = new Stack();
stack.push() 元素入栈
stack.pop() 栈顶元素出栈
stack.peek() 查看栈顶元素
stack.size() 查看栈的大小
stack.empty()判断栈是否为空, true or false
stack.serch(** ***)查找元素 ,返回int. 若找到返回位置,找不到返回-1*/
if(root == null)
return;
Stack<Node> stack = new Stack<Node>();
stack.push(root);
while(!stack.isEmpty()){
Node cur = stack.pop();
System.out.println(cur.e);
if(cur.right != null)
stack.push(cur.right);
if(cur.left != null)
stack.push(cur.left);
}
}
//二分搜索树的中序遍历
public void midOrder() {
midOrder(root);
}
//中序遍历以node为根的二分搜索树, 递归算法
public void midOrder(Node node) {
if(node==null){
return;
}
midOrder(node.left);
System.out.println(node.e);
midOrder(node.right);
}
// 二分搜索树的后序遍历
public void postOrder(){
postOrder(root);
}
// 后序遍历以node为根的二分搜索树, 递归算法
private void postOrder(Node node){
if(node == null)
return;
postOrder(node.left);
postOrder(node.right);
System.out.println(node.e);
}
// 二分搜索树的层序遍历
public void levelOrder(){
if(root == null)
return;
Queue<Node> q = new LinkedList<>();//用链表实现的队列
q.add(root);
while(!q.isEmpty()){
Node cur = q.remove();
System.out.println(cur.e);
if(cur.left != null)
q.add(cur.left);
if(cur.right != null)
q.add(cur.right);
}
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
generateBSTString1(root, 0, res);//前序遍历
interval(res);//插入间隔
generateBSTString2(root, 0, res);//中序遍历
interval(res);
generateBSTString3(root, 0, res);//后序遍历
return res.toString();
}
//定义一个间隔形式
public void interval(StringBuilder res) {
res.append("********************************************************************************\n");
}
// 生成以node为根节点,深度为depth的描述二叉树的字符串,运用前序遍历
private void generateBSTString1(Node node, int depth, StringBuilder res){//节点,深度 ,字符串
if(node == null){
res.append(generateDepthString(depth) + "null\n");
return;
}
res.append(generateDepthString(depth) + node.e + "\n");//前序遍历
generateBSTString1(node.left, depth + 1, res);
generateBSTString1(node.right, depth + 1, res);
}
//生成树枝的函数
private String generateDepthString(int depth){
StringBuilder res = new StringBuilder();
for(int i = 0 ; i < depth ; i ++)
res.append("--");
return res.toString();
}
//生成以node为根节点,深度为depth的描述二叉树的字符串,运用中序遍历
private void generateBSTString2(Node node, int depth, StringBuilder res){//节点,深度 ,字符串
if(node == null){
res.append(generateDepthString(depth) + "null\n");
return;
}
generateBSTString2(node.left, depth + 1, res);
res.append(generateDepthString(depth) + node.e + "\n");//中序遍历
generateBSTString2(node.right, depth + 1, res);
}
//生成以node为根节点,深度为depth的描述二叉树的字符串,运用后序遍历
private void generateBSTString3(Node node, int depth, StringBuilder res){//节点,深度 ,字符串
if(node == null){
res.append(generateDepthString(depth) + "null\n");
return;
}
generateBSTString3(node.left, depth + 1, res);
generateBSTString3(node.right, depth + 1, res);
res.append(generateDepthString(depth) + node.e + "\n");//后序遍历
}
//删除最小值
public void min() {
min(this.root);
}
public void min(Node node) {
if(node==null||(node.right==null&&node.left==null)) {
System.out.println("二叉树无法进行该操作(0或1个节点)");
return;
}
else if(node.left==null) {
root=node.right;
return;
}
else if(node.left.left==null) {//node.left就是最小的
if(node.left.right==null) //最小的节点是叶节点
node.left=null;
else if(node.left.right!=null)
node.left=node.left.right;
}
else {
min(node.left);
}
}
//删除最大值
public void max() {
max(root);
}
public void max(Node node) {
if(node==null||(node.left==null&&node.right==null)) {
System.out.println("二叉树无法进行该操作(0或1个节点)");
return;
}
else if(node.right==null) {
root=node.left;
return;
}
else if(node.right.right==null) {//node.right就是最大的
if(node.right.left==null) //最大的节点是叶节点
node.right=null;
else if(node.right.left!=null)
node.right=node.right.left;
}
else {
max(node.right);
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
BST bst=new BST<Integer>();
BST bst1=new BST<Integer>();
//System.out.println(bst1.toString());
bst.add(4);
bst.add(6);
bst.add(5);
bst.add(2);
bst.add(7);
bst.add(1);
bst.add(3);
//System.out.println(bst.contains(3));//是否包含3
/*System.out.println(bst.toString());//显示出位置分别前序,中序,后序遍历二叉树的值
bst.preOrder();//仅前序遍历二叉树的值
System.out.println("********************************************************************************");
//bst. preOrderNR();//非递归方式前序遍历二叉树的值
// System.out.println("********************************************************************************");
*/ bst.midOrder();//仅中序遍历二叉树的值
/*System.out.println("********************************************************************************");
bst.postOrder();//仅后序遍历二叉树的值
System.out.println("********************************************************************************");
bst. levelOrder();//二叉树的层序遍历
*/System.out.println("********************************************************************************");
bst.min();//去掉最小的元素
bst.midOrder();//仅中序遍历二叉树的值
System.out.println("********************************************************************************");
bst.max();//去掉最大的元素
bst.midOrder();//仅中序遍历二叉树的值
//因为内部类是私有的所以不能这样访问其中的成员方法(getE()),即使该方法是public的
//只能在外部类中定义一个函数out(), 因为内部私有类只能被其外围类使用
//所以其定义是不可以具体实现的,也就是不可以对外进行实例化,
//只能由其外部对象(root)使用相应方法进行完成
}
}
输出结果(用仅显示数值的中序遍历来验证结果)
1
2
3
4
5
6
7
********************************************************************************
2
3
4
5
6
7
********************************************************************************
2
3
4
5
6