树的接口:
public interface Tree<E> extends Iterable<E> {
public boolean search(E e);
public boolean insert(E e);
public boolean delete(E e);
public void inorder();
public void postorder();
public void preorder();
public int getSize();
public boolean isEmpty();
}
抽象类树:
import java.util.Iterator;
public abstract class AbstractTree<E> implements Tree<E> {
@Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean search(E e) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean insert(E e) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean delete(E e) {
// TODO Auto-generated method stub
return false;
}
@Override
public void inorder() {
// TODO Auto-generated method stub
}
@Override
public void postorder() {
// TODO Auto-generated method stub
}
@Override
public void preorder() {
// TODO Auto-generated method stub
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return getSize()==0;
}
}
BST树:
public class BST<E extends Comparable<E>> extends AbstractTree<E> {
protected TreeNode<E> root;
protected int size=0;
public BST() {
}
public BST(E[] objects) {
for(int i=0;i<objects.length;i++) {
insert(objects[i]);
}
}
public boolean search(E e) {
TreeNode<E> current=root;
while(current!=null) {
if(e.compareTo(current.element)<0)
current=current.left;
else if(e.compareTo(current.element)>0)
current=current.right;
else return true;
}
return false;
}
public boolean insert(E e) {
if(root==null)
root=createNewNode(e);
else {
TreeNode<E> parent=null;
TreeNode<E> current=root;
while(current!=null)
if(e.compareTo(current.element)<0) {
parent=current;
current=current.left;
}
else if(e.compareTo(current.element)>0) {
parent=current;
current=current.right;
}
else
return false;
if(e.compareTo(parent.element)<0)
parent.left=createNewNode(e);
else
parent.right=createNewNode(e);
}
size++;
return true;
}
protected TreeNode<E> createNewNode(E e){
return new TreeNode<>(e);
}
public void inorder() {
inorder(root);
}
public void inorder(TreeNode<E> root) {
if(root==null) return;
inorder(root.left);
System.out.print(root.element+" ");
inorder(root.right);
}
public void postorder() {
postorder(root);
}
protected void preorder(TreeNode<E> root) {
if(root==null) return;
postorder(root.left);
postorder(root.right);
System.out.print(root.element+" ");
}
public void preorder() {
preorder(root);
}
public void postorder(TreeNode<E> root) {
if(root==null) return;
System.out.print(root.element);
preorder(root.left);
preorder(root.right);
}
public int getSize() {
return size;
}
public TreeNode<E> getRoot(){
return root;
}
public java.util.ArrayList<TreeNode<E>> path(E e){
java.util.ArrayList<TreeNode<E>> list=new java.util.ArrayList<>();
TreeNode<E> current=root;
while(current!=null) {
list.add(current);
if(e.compareTo(current.element)<0) {
current=current.left;
}
else if(e.compareTo(current.element)>0)
current=current.right;
else
break;
}
return list;
}
public boolean delete(E e) {
TreeNode<E> parent=null;
TreeNode<E> current=root;
while(current!=null) {
if(e.compareTo(current.element)<0) {
parent=current;
current=current.left;
}
else if(e.compareTo(current.element)>0) {
parent=current;
current=current.right;
}
else
break;
}
if(current==null)
return false;
if(current.left==null) {
if(parent==null)
root=current.right;
else
if(e.compareTo(parent.element)<0)
parent.left=current.right;
else
parent.right=current.right;
}
else {
TreeNode<E> parentOfRightMost=current;
TreeNode<E> rightMost=current.left;
while(rightMost.right!=null) {
parentOfRightMost=rightMost;
rightMost=rightMost.right;
}
current.element=rightMost.element;
if(parentOfRightMost.right==rightMost)
parentOfRightMost.right=rightMost.left;
else
parentOfRightMost.left=rightMost.left;
}
size++;
return true;
}
public java.util.Iterator<E> iterator(){
return new InorderIterator();
}
public static class TreeNode<E extends Comparable<E>>{
protected E element;
protected TreeNode<E> left;
protected TreeNode<E> right;
public TreeNode(E e) {
element=e;
}
}
private class InorderIterator implements java.util.Iterator<E>{
private java.util.ArrayList<E> list=new java.util.ArrayList<>();
private int current=0;
public InorderIterator() {
inorder();
}
private void inorder() {
inorder(root);
}
private void inorder(TreeNode<E> root) {
if(root==null) return;
inorder(root.left);
list.add(root.element);
inorder(root.right);
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
if(current<list.size())
return true;
return false;
}
@Override
public E next() {
// TODO Auto-generated method stub
return list.get(current++);
}
public void remove() {
delete(list.get(current));
list.clear();
inorder();
}
public void clear() {
root=null;
size=0;
}
}
}
将树用javafx演示:
import javafx.application.*;
import javafx.geometry.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.*;
public class BSTAnimation extends Application{
@Override
public void start(Stage primaryStage) throws Exception {
// TODO Auto-generated method stub
BST<Integer> tree=new BST<>();
BorderPane pane=new BorderPane();
BTView view=new BTView(tree);
pane.setCenter(view);
TextField tfKey=new TextField();
tfKey.setPrefColumnCount(3);
tfKey.setAlignment(Pos.BASELINE_RIGHT);
Button btInsert=new Button("Insert");
Button btDelete=new Button("Delete");
HBox hbox=new HBox(5);
hbox.getChildren().addAll(new Label("Enter a key: "),tfKey,btInsert,btDelete);
hbox.setAlignment(Pos.CENTER);
pane.setBottom(hbox);
btInsert.setOnAction(e->{
int key=Integer.parseInt(tfKey.getText());
if(tree.search(key)) {
view.displayTree();
view.setStatus(key+" is already in the tree");
}
else {
tree.insert(key);
view.displayTree();
view.setStatus(key+" is inserted in the tree");
}
});
btDelete.setOnAction(e->{
int key=Integer.parseInt(tfKey.getText());
if(!tree.search(key)) {
view.displayTree();
view.setStatus(key+" is not in the tree");
}
else {
tree.delete(key);
view.displayTree();
view.setStatus(key+" is deleted from the tree");
}
});
Scene scene=new Scene(pane,450,250);
primaryStage.setTitle("BSTAnimation");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Application.launch(args);
}
public class BTView extends Pane{
private BST<Integer> tree=new BST<>();
private double radius=15;
private double vGap=50;
BTView(BST<Integer> tree){
this.tree=tree;
setStatus("Tree is empty");
}
public void setStatus(String msg) {
getChildren().add(new Text(20,20,msg));
}
public void displayTree() {
this.getChildren().clear();
if(tree.getRoot()!=null) {
displayTree(tree.getRoot(),getWidth()/2,vGap,getWidth()/4);
}
}
public void displayTree(BST.TreeNode<Integer> root,double x,double y,double hGap) {
if(root.left!=null) {
getChildren().add(new Line(x-hGap,y+vGap,x,y));
displayTree(root.left,x-hGap,y+vGap,hGap/2);
}
if(root.right!=null) {
getChildren().add(new Line(x+hGap,y+vGap,x,y));
displayTree(root.right,x+hGap,y+vGap,hGap/2);
}
Circle circle=new Circle(x,y,radius);
circle.setFill(Color.WHITE);
circle.setStroke(Color.BLACK);
getChildren().addAll(circle,new Text(x-4,y+4,root.element+""));
}
}
}