代碼如下(附有註釋):
package DataStructureDemo.com.ds.tree;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class BinarySearchTree<E extends Comparable<E>> {
private class Node{
E val;
Node left,right;
Node(E val) {
this.val = val;
}
}
private Node root;//二叉搜索樹的根結點
private int size;//二叉搜索樹中元素個數
//構造器,默認生成一個空二叉搜索樹
private BinarySearchTree() {
this.root = null;
this.size = 0;
}
public int getSize() {
return size;
}
public boolean isEmpty(){
return this.size == 0;
}
//向二分搜索樹中添加新元素
public void add(E e){
root = add(root,e);
}
//向以node爲根結點的樹中插入元素e(遞歸)
//返回插入新節點後二叉樹的根
private Node add(Node node,E e){
if(node == null){
size++;
return new Node(e);
}
//要插入元素小於根節點值,使用遞歸
if(e.compareTo(node.val) <0){
node.left = add(node.left,e);
}else if(e.compareTo(node.val) >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.val) == 0){
return true;
} else if(e.compareTo(node.val) <0) {
return contains(node.left,e);
} else {
return contains(node.right,e);
}
}
//二叉搜索樹的前序遍歷
public void PreOrder(){
PreOrder(root);
}
//前序遍歷以node爲根節點的二叉搜索樹(遞歸)
//先訪問根節點,再訪問左右子樹
private void PreOrder(Node node){
//遞歸終止條件
if(node == null){
return;
}
System.out.print(node.val+" ");
if (node.left != null) {
PreOrder(node.left);
}
if (node.right != null) {
PreOrder(node.right);
}
}
//前序遍歷的非遞歸寫法,用棧來記錄遍歷的過程
public void PreOrderNR(){
Stack<Node> stack = new Stack<>();
stack.push(root);//先將根節點壓入棧中,作爲前序遍歷第一個訪問的
while(!stack.isEmpty()){
Node cur = stack.pop();
System.out.print(cur.val+" ");//訪問節點
//鑑於棧後進先出的性質,應先將右子樹壓入棧中
if(cur.right != null){
stack.push(cur.right);
}
if(cur.left != null){
stack.push((cur.left));
}
}
}
//中序遍歷 先訪問左子樹,再訪問根節點,最後訪問右子樹
public void Inorder(){
Inorder(root);
}
private void Inorder(Node node) {
if(node == null){
return;
}
if(node.left != null){
Inorder(node.left);
}
System.out.print(node.val+" ");
if(node.right != null){
Inorder(node.right);
}
}
//後序遍歷 先訪問左右子樹,再訪問根節點
public void PostOrder() {
postOrder(root);
}
private void postOrder(Node node){
if(node == null) {
return;
}
if (node.left != null) {
postOrder(node.left);
}
if (node.right != null) {
postOrder(node.right);
}
System.out.print(node.val+" ");
}
//層序遍歷(非遞歸形式)
public void LevelOrder(){
Queue<Node> q = new LinkedList<>();
q.add(root);
while(!q.isEmpty()){
Node cur = q.remove();
System.out.print(cur.val+" ");
if(cur.left != null){
q.add(cur.left);
}
if(cur.right != null){
q.add(cur.right);
}
}
}
public E getMin() {
if(root == null){
throw new IllegalArgumentException();
}
Node node = getMinNode(root);
return node.val;
}
//查找以node爲根節點的二叉搜索樹的最小值節點
private Node getMinNode(Node node){
return (node.left != null) ? getMinNode(node.left) : node;
}
public E getMax() {
if(root == null){
throw new IllegalArgumentException();
}
Node node = getMaxNode(root);
return node.val;
}
//查找查找以node爲根節點的二叉搜索樹的最大值節點
private Node getMaxNode(Node node){
return (node.right == null) ? node : getMaxNode(node.right);
}
public E RemoveMin(){
E res = getMin();
root = RemoveMinNode(root);
return res;
}
//刪除傳入二叉樹的最小值節點
private Node RemoveMinNode(Node node){
//找到需要刪除的節點(遞歸終止條件)
if(node.left == null){
Node rightnode = node.right;
node.right = null;
size--;
return rightnode;
}
//繼續向左走,刪除最小值節點
node.left = RemoveMinNode(node.left);
return node;
}
public E RemoveMax() {
E res = getMax();
root = RemoveMaxNode(root);
return res;
}
private Node RemoveMaxNode(Node node){
if(node.right == null){
Node leftnode = node.left;
node.left = null;
size--;
return leftnode;
}
node.right = RemoveMaxNode(node.right);
return node;
}
//移除二叉樹中指定值的節點
public void remove(E e) {
root = remove(root,e);
}
private Node remove(Node node,E e){
if(node == null){
return null;
}
//需要刪除的節點在左子樹中
if(e.compareTo(node.val) <0){
node.left = remove(node.left,e);
}
//需要刪除的節點在右子樹中
else if(e.compareTo(node.val) >0){
node.right = remove(node.right,e);
}
//此時node即爲需要刪除的節點
else {
//若此時節點只有一邊孩子,返回左子樹作爲新的根
if(node.left != null && node.right == null){
Node leftnode = node.left;
size--;
node.left = null;
return leftnode;
}
// 返回右子樹作爲新的根
if(node.right != null && node.left == null){
Node rightnode = node.right;
size--;
node.right = null;
return rightnode;
}
// 左右子樹都存在,返回後繼節點(右子樹最左葉子)作爲新的根
if(node.left != null){
Node successor = getMinNode(node.right);
successor.left = node.left;
successor.right = RemoveMinNode(node.right);
node.left = node.right = null;
return successor;
}
}
return node;
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
generateString(root, 0, res);
return res.toString();
}
// 生成以node爲根節點,深度爲depth的描述二叉樹的字符串
private void generateString(Node node, int depth, StringBuilder res){
if(node == null){
res.append(generateDepthString(depth)).append("null\n");
return;
}
res.append(generateDepthString(depth)).append(node.val).append("\n");
generateString(node.left, depth + 1, res);
generateString(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();
}
public static void main(String[] args) {
BinarySearchTree<Integer> bst = new BinarySearchTree<>();
int[] a = {5,3,6,8,4,2};
for (int k : a) {
bst.add(k);
}
System.out.println("遞歸前序遍歷結果爲:");
bst.PreOrder();//前序遍歷
System.out.println();
System.out.println("遞歸後序遍歷結果爲:");
bst.PostOrder();//後序遍歷
System.out.println();
System.out.println("遞歸中序遍歷結果爲:");
bst.Inorder();//中序遍歷
System.out.println();
/*System.out.println(bst.getMax());
System.out.println(bst.getMin());*/
System.out.println("非遞歸前序遍歷結果爲:");
bst.PreOrderNR();
//System.out.println(bst.toString());
System.out.println();
System.out.println("層序遍歷結果爲:");
bst.LevelOrder();
}
}