package ctgu.sugite.content.character12;
import ctgu.sugite.content.character10.LinkedStack;
public class BinarySearchTree<E> {
private static class TreeNode<E> {
E key;
TreeNode<E> lChild;
TreeNode<E> rChild;
TreeNode<E> parent;
public TreeNode(E e, TreeNode<E> left, TreeNode<E> right,
TreeNode<E> parent) {
this.key = e;
this.lChild = left;
this.rChild = right;
this.parent = parent;
}
}
private TreeNode<E> root = new TreeNode<E>(null, null, null, null);
public BinarySearchTree() {
root.parent = root.lChild = root.rChild = root;
}
public void treeInorder(TreeNode<E> tn) {// 非遞歸的中序遍歷
LinkedStack<TreeNode<E>> stack = new LinkedStack<TreeNode<E>>();
TreeNode<E> p = tn;
while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);
p = p.lChild;
} else {
p = stack.pop();
System.out.print(p.key + " ");
p = p.rChild;
}
}
System.out.println();
}
public TreeNode<E> treeSearch(TreeNode<E> tn, E e) {// 二叉查找
int result = compare(e, tn.key);
if (result == 0 || tn == null)
return tn;
if (result < 0)
return treeSearch(tn.lChild, e);
else
return treeSearch(tn.rChild, e);
}
public TreeNode<E> treeMinimum(TreeNode<E> tn) {// 樹中最小值
while (tn.lChild != null)
tn = tn.lChild;
return tn;
}
public TreeNode<E> treeMaximum(TreeNode<E> tn) {// 樹中最大值
while (tn.rChild != null)
tn = tn.rChild;
return tn;
}
public TreeNode<E> treeSuccessor(TreeNode<E> tn) {// 結點後繼
if (tn.rChild != null)
return treeMinimum(tn.rChild);
TreeNode<E> p = tn.parent;
while (p != null && tn == p.rChild) {
tn = p;
p = p.parent;
}
return p;
}
public TreeNode<E> treePredecessor(TreeNode<E> tn) {// 結點前趨
if (tn.lChild != null)
return treeMaximum(tn.lChild);
TreeNode<E> p = tn.parent;
while (p != null && tn == p.lChild) {
tn = p;
p = p.parent;
}
return p;
}
public void treeInsert(BinarySearchTree<E> tree, E e) {// 插入結點
TreeNode<E> z = new TreeNode<E>(e, null, null, null);
TreeNode<E> y = new TreeNode<E>(null, null, null, null);
TreeNode<E> x = tree.getRoot();
while (x.key != null) {
y = x;
if (compare(e, x.key) < 0)
x = x.lChild;
else
x = x.rChild;
if (x == null) {
x = new TreeNode<E>(null, null, null, null);
}
}
z.parent = y;
if (y.key == null) {
tree.setRoot(z);
} else {
if (compare(e, y.key) < 0)
y.lChild = z;
else
y.rChild = z;
}
}
public TreeNode<E> treeDelete(BinarySearchTree<E> tree, E e) {// 刪除結點
TreeNode<E> z = treeSearch(tree.getRoot(), e);
TreeNode<E> y = new TreeNode<E>(null, null, null, null);
TreeNode<E> x = new TreeNode<E>(null, null, null, null);
if (z.lChild == null || z.rChild == null)
y = z;
else
y = treeSuccessor(z);
x = (y.lChild == null) ? y.rChild : y.lChild;
if (x != null)
x.parent = y.parent;
if (y.parent == null)
tree.setRoot(x);
else {
if (y == y.parent.lChild)
y.parent.lChild = x;
else
y.parent.rChild = x;
}
if (y != z)
z.key = y.key;
return y;
}
public TreeNode<E> getRoot() {
return this.root;
}
public void setRoot(TreeNode<E> root) {
this.root = root;
}
@SuppressWarnings({ "unchecked" })
private int compare(E a, E b) {
return ((Comparable<E>) a).compareTo(b);
}
public static void main(String[] args) {
BinarySearchTree<Integer> bst = new BinarySearchTree<Integer>();
int[] a = { 50, 9, 3, 78, 23, 0, 2, 4, 6, 6 };
for (int i = 0; i < a.length; i++) {
bst.treeInsert(bst, new Integer(a[i]));
}
bst.treeInorder(bst.getRoot());
bst.treeDelete(bst, new Integer(6));
bst.treeInorder(bst.getRoot());
bst.treeDelete(bst, new Integer(0));
bst.treeInorder(bst.getRoot());
System.out.println("root is :" + bst.getRoot().key);
System.out.println("root's successor is :"
+ bst.treeSuccessor(bst.getRoot()).key);
System.out.println("root's predecessor is :"
+ bst.treePredecessor(bst.getRoot()).key);
System.out.println("max value is :"
+ bst.treeMaximum(bst.getRoot()).key);
System.out.println("min value is :"
+ bst.treeMinimum(bst.getRoot()).key);
}
}
運行結果:
0 2 3 4 6 6 9 23 50 78
0 2 3 4 6 9 23 50 78
2 3 4 6 9 23 50 78
root is :50
root's successor is :78
root's predecessor is :23
max value is :78
min value is :2
要用到的鏈棧可以採用java的LinkedList實現,也可自己實現(或者直接採用遞歸方式進行中序遍歷)
package ctgu.sugite.content.character10;
public class LinkedStack<E> implements Stack<E> {
private int size;
private StackNode<E> topNode;
public LinkedStack() {
this.size = 0;
this.topNode = null;
}
@Override
public boolean push(E e) {
this.topNode = new StackNode<E>(e, this.topNode);
this.size++;
return true;
}
@Override
public E pop() {
if (isEmpty())
return null;
E e = topNode.element;
topNode = topNode.next;
this.size--;
return e;
}
@Override
public boolean isEmpty() {
return this.size == 0;
}
@Override
public E peek() {
if (isEmpty())
return null;
return topNode.element;
}
}
package ctgu.sugite.content.character10;
class StackNode<E> {
E element;
StackNode<E> next;
public StackNode(E e) {
this(e, null);
}
public StackNode(E e, StackNode<E> n) {
this.element = e;
this.next = n;
}
}
package ctgu.sugite.content.character10;
public interface Stack<E> {
boolean push(E e);
E pop();
boolean isEmpty();
E peek();
}