一、BST的实现
BST的结点需要具有可比较 所以需要extends Comparable。
左孩子比父节点小,右孩子比父节点大。
二、代码实现
基本构造
public class BST<E extends Comparable<E>> {
private class Node {
public Node left, right;
public E e;
public Node(E e) {
this.left = null;
this.right = null;
this.e = e;
}
}
private Node root;
private int size;
添加元素(优化递归条件)
public void add(E e) {
root=add(root, e);
}
private Node add(Node node, E e) {
if (node == null) {
size++;
return new Node(e);
}
if (e.compareTo(node.e) > 0)
node.right=add(node.right, e);
else if (e.compareTo(node.e) < 0)
node.left=add(node.left, e);
return node;
}
遍历
由于前中后序遍历基本相同,这里给出前序遍历
public void preOrder(){
preOrder(root);
}
private void preOrder(Node node){
if (node==null)
return;
System.out.println(node.e);
preOrder(node.left);
preOrder(node.right);
}
前序遍历非递归
前序递归的非递归由栈来实现。
首先将root入栈,然后出栈
然后先将出栈的结点的右孩子入栈,再将左孩子入栈。
以此类推
public void NRpreOrder() {
Stack<Node> stack=new Stack<>();
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 NRminOrder() {
Node cur = root;
if (cur == null)
return;
Stack<Node> stack = new Stack<Node>();
while (!stack.isEmpty() || cur != null) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
cur = stack.pop();
System.out.println(cur.e);
cur = cur.right;
}
}
}
后序遍历非递归双栈法
public static void posOrderUnRecur1(Node head) {
System.out.print("pos-order: ");
if (head != null) {
Stack<Node> s1 = new Stack<Node>();//双栈法
Stack<Node> s2 = new Stack<Node>();
s1.push(head);
while (!s1.isEmpty()) {
head = s1.pop();
s2.push(head);
if (head.left != null) {
s1.push(head.left);
}
if (head.right != null) {
s1.push(head.right);
}
}
while (!s2.isEmpty()) {
System.out.print(s2.pop().value + " ");
}
}
System.out.println();
}
层序遍历
public void levelTraversal(){
Node cur=root;
if (cur==null)
return;
Queue<Node> queue=new LinkedList<>();
queue.add(cur);
while (!queue.isEmpty()){
cur=queue.poll();
System.out.println(cur.e);
if (cur.left!=null)
queue.add(cur.left);
if (cur.right!=null)
queue.add(cur.right);
}
删除最小或者最大元素,和某个元素
//找到BST中最大或者最小值
public E maximum(){
return maximum(root);
}
private E maximum(Node node){
if (node.right==null)
return node.e;
else return maximum(node.right);
}
//删除最大值
public E removeMax(){
removeMax(root);
return maximum();
}
private Node removeMax(Node node){
if (node.right==null){
Node leftNode=node.left;
node.left=null;
return leftNode;
}
node.right=removeMax(node.right);
return node;
}
删除任意值
删除任意值用到了removeMin() minimum()等方法。
private Node minimum(Node node) {
if (node.left == null)
return node;
else return minimum(node.left);
}
private Node removeMin(Node node){
if (node.left==null) {
Node rightnode = node.right;
node.right=null;
size--;
return rightnode;
}
node.left=removeMin(node.left);
return node;
}
关键在于当删除结点有左右子树时候,需要找到删除结点的后继者。
后继者就是被删除结点的 右子树的最小值。
private Node remove(Node node, E e) {
if (node == null)
return null;
if (e.compareTo(node.e) > 0){
node.right=remove(node.right,e);
return node;
}
else if (e.compareTo(node.e) < 0){
node.left=remove(node.left,e);
return node;
}
else {
if (node.left == null) {
Node rightnode = node.right;
node.right = null;
size--;
return rightnode;
} else if (node.right == null) {
Node leftnode = node.right;
node.left = null;
size--;
return leftnode;
} else {Node successor=minimum(node.right);
successor.right=removeMin(node.right);
successor.left=node.left;
node.left=node.right=null;
return successor;
}
}
}