本篇主要针对了ADT(二叉查找树)和AVL树的基本操作进行了总结:包括:创建,删除整树,插入,删除节点,寻找最大、最小数、遍历树操作。
首先是二叉查找树:
/*
* 二叉查找树 利用泛型创建的二叉查找树是一个泛型类
*/
class BinarySearchTree<AnyType extends Comparable<? super AnyType>>{
/*
* 节点函数
*/
private static class BinaryNode<AnyType>{
AnyType element;
BinaryNode<AnyType> left;
BinaryNode<AnyType> right;
BinaryNode(AnyType element) {
this(element,null,null);
}
BinaryNode(AnyType element , BinaryNode<AnyType> lt,BinaryNode<AnyType> rt){
this.element = element;
this.right = rt;
this.left = lt;
}
}
private BinaryNode<AnyType> root;
public BinarySearchTree(){
root = null;
}
public void makeEmpty(){
root = null;
}
public boolean isEmpty(){
return root == null;
}
/*
* 检测包含方法
*/
public boolean contains(AnyType x){
return contains(x,root);
}
/*
* 寻找最小值的节点
*/
public AnyType findMin(){
if(isEmpty()){
;
}
return findMin(root).element;
}
/*
* 寻找最大值的节点
*/
public AnyType findMax(){
if(isEmpty()){
;
}
return findMax(root).element;
}
/*
* 插入此值的节点
*/
public void insert(AnyType x){
root = insert(x,root);
}
/*
* 删除此值的节点
*/
public void remove(AnyType x){
root = remove(x,root);
}
/*
* 打印二叉查找树
*/
public void printTree(){
if(isEmpty()){
System.out.println("Empty tree");
}else{
printTree(root);
}
}
/*
* 递归实现二叉查找树中的查询
*/
private boolean contains(AnyType x , BinaryNode<AnyType> t){
if(t == null){
return false;
}
int result = x.compareTo(t.element);
if(result < 0){
return contains(x, t.left);
}else if(result > 0){
return contains(x,t.right);
}else{
return true;
}
}
/*
* 递归实现二叉查找树中的寻找最小节点
*/
private BinaryNode<AnyType> findMin(BinaryNode<AnyType> t){
if(t == null)
return null;
else if(t.left != null)
return findMin(t.left);
else
return t;
}
/*
* 循环实现二叉查找树中的寻找最大节点
*/
private BinaryNode<AnyType> findMax(BinaryNode<AnyType> t){
if(t != null)
while(t.right != null)
t = t.right;
return t;
}
/*
* 递归实现二叉查找树中插入
*/
private BinaryNode<AnyType> insert(AnyType x , BinaryNode<AnyType> t){
if(t== null){
return new BinaryNode<AnyType>(x);
}
int result = x.compareTo(t.element);
if(result < 0){
t.left = insert(x,t.left);
}else if(result > 0){
t.right = insert(x , t.right);
}else{
;
}
return t;
}
/*
* 懒惰删除二叉查找树中的节点 如果有两个儿子就把右子树的最大数作为根值、并在右子树中删除
*/
private BinaryNode<AnyType> remove(AnyType x , BinaryNode<AnyType> t){
if(t == null)
return null;
int result = x.compareTo(t.element);
if(result < 0){
t.left = remove(x,t.left);
}else if(result > 0){
t.right = remove(x,t.right);
}else if(t.left != null && t.right != null){
t.element = findMin(t.right).element;
t.right = remove(t.element , t.right);
}else{
t = (t.left != null) ? t.left:t.right;
}
return t;
}
/*
* 打印二叉查找树
*/
private void printTree(BinaryNode<AnyType> t){
if(t !=null){
printTree(t.left);
System.out.print(t.element);
printTree(t.right);
}
}
}
</pre><pre name="code" class="java">接下来是AVL树
</pre><pre name="code" class="java"><pre name="code" class="java">/*
* 平衡树类
*/
class AVLTree<T extends Comparable<? super T>>{
/*
* 平衡树节点,比二叉查找树多了一个高度参数,用来检测左右子树高度差
*/
private static class AvlNode<T>{
T element;
AvlNode<T> left;
AvlNode<T> right;
int height;
AvlNode(T element){
this(element, null , null);
}
AvlNode(T element , AvlNode<T> lt , AvlNode<T> rt){
this.element = element;
this.left = lt;
this.right = rt;
this.height = 0;
}
}
private AvlNode<T> root;
AVLTree(){
root = null;
}
public void makeEmpty(){
root = null;
}
public boolean isEmpty(){
return root == null;
}
public void insert(T x){
root = insert(x , root);
}
public T findMin(){
return findMin(root);
}
public T findMax(){
return findMax(root);
}
public void remove(T x){
root = remove(x ,root);
}
public boolean contains(T x){
return contains(x,root);
}
public void printTree(){
if(isEmpty())
System.out.println("Empty tree");
else
printTree(root);
}
/*
* AVL树 插入操作:1.判断插入点,2.检测左右树高的差距是否符合要求 3.树高不符合AVL要求时,判断引起原因,进行相应的旋转操作
*/
private AvlNode<T> insert(T x, AvlNode<T> t){
if(t == null)
return new AvlNode<T>(x , null ,null);
int result = x.compareTo(t.element);
if(result < 0){
t.left = insert(x, t.left);
if(height(t.left) - height(t.right) ==2){
if(x.compareTo(t.left.element) < 0)
t = rotateWithLeftChild(t);
else
t = doubleWithLeftChild(t);
}
}else if(result > 0){
t.right = insert(x, t.right);
if(height(t.right) - height(t.left) ==2){
if(x.compareTo(t.right.element) > 0)
t = rotateWithRightChild(t);
else
t = doubleWithRightChild(t);
}
}else
;
t.height = Math.max(height(t.left), height(t.right))+1;
return t;
}
/*
* 单旋转 左侧
*/
private AvlNode<T> rotateWithLeftChild(AvlNode<T> k2){
AvlNode<T> k1 = k2.left;
k2.left = k1.right;
k1.right = k2;
k2.height = Math.max(height(k2.left), height(k2.right))+1;
k1.height = Math.max(height(k1.left), height(k1.right))+1;
return k1;
}
/*
* 单旋转右侧
*/
private AvlNode<T> rotateWithRightChild(AvlNode<T> k2){
AvlNode<T> k1 = k2.right;
k2.right = k1.left;
k1.left = k2;
k2.height = Math.max(height(k2.left), height(k2.right))+1;
k1.height = Math.max(height(k1.left), height(k1.right))+1;
return k1;
}
/*
* 双旋转左侧(先右旋后左旋)
*/
private AvlNode<T> doubleWithLeftChild(AvlNode<T> k3){
k3.left = rotateWithRightChild(k3.left);
return rotateWithLeftChild(k3);
}
/*
* 单旋转右侧(先左旋后右旋)
*/
private AvlNode<T> doubleWithRightChild(AvlNode<T> k3){
k3.right = rotateWithLeftChild(k3.right);
return rotateWithRightChild(k3);
}
private T findMin(AvlNode<T> t){
if(t == null)
return null;
else if(t.left !=null)
return findMin(t.left);
else
return t.element;
}
private T findMax(AvlNode<T> t){
if(t != null)
while(t.right != null)
t= t.right;
return t.element;
}
/*
* AVL树的删除节点 1.寻找删除节点的位置 2.判断删除之后树高是否满足AVL要求 3.如果不满足,在对树高较高的树进行判断、旋转 3.比插入相比要
<span style="white-space:pre"> </span> * 加一个非空判断。
*/
private AvlNode<T> remove(T x , AvlNode<T> t){
if(t ==null)
return null;
int result = x.compareTo(t.element);
if(result < 0){
t.left = remove(x , t.left);
if(height(t.right) - height(t.left) == 2){
if(height(t.right.left) - height(t.right.right) == 1){
t = doubleWithRightChild(t);
}else{
t = rotateWithRightChild(t);
}
}
}else if(result > 0){
t.right = remove(x ,t.right);
if(height(t.left) - height(t.right) == 2){
if(height(t.left.right) - height(t.left.left) == 1){
t = doubleWithLeftChild(t);
}else{
t = rotateWithLeftChild(t);
}
}
}else if(t.right != null && t.left != null){
if(height(t.left) >= height(t.right)){
t.element = findMax(t.left);
t.left = remove(t.element , t.left);
}else {
t.element = findMin(t.right);
t.right = remove(t.element , t.right);
}
}else{
t = (t.left != null)? t.left: t.right;
}
if(t != null)
t.height = Math.max(height(t.left), height(t.right))+1;
return t;
}
/*
* AVL树查询
*/
private boolean contains(T x, AvlNode<T> t){
if(t == null)
return false;
int result = x.compareTo(t.element);
if(result < 0)
return contains(x, t.left);
else if(result > 0)
return contains(x, t.right);
else
return true;
}
/*
* 遍历AVL树
*/
private void printTree(AvlNode<T> t){
if(t != null){
printTree(t.left);
System.out.print(t.element.toString() +"(" +height(t)+")");
printTree(t.right);
}
}
public int height(){
return height(root);
}
private int height(AvlNode<T> t){
return t == null? -1:t.height;
}
}
测试程序
<pre name="code" class="java">public class TreeTest {
public static void main(String[] args){
BinarySearchTree<Integer> BST = new BinarySearchTree<>();
BST.insert(3);
BST.insert(1);
BST.insert(4);
BST.insert(6);
BST.insert(9);
BST.insert(2);
BST.insert(5);
BST.insert(7);
BST.printTree();
System.out.println();
if(BST.contains(5)){
System.out.println("Contains five");
}
BST.remove(5);
BST.printTree();
System.out.println();
System.out.println(BST.findMax()+"");
System.out.println(BST.findMin()+"");
if(!BST.contains(5)){
System.out.println("Contains not five");
}
AVLTree<Integer> AVLT = new AVLTree<>();
AVLT.insert(3);
AVLT.insert(1);
AVLT.insert(4);
AVLT.insert(6);
AVLT.insert(9);
AVLT.insert(2);
AVLT.insert(5);
AVLT.insert(7);
AVLT.printTree();
System.out.println();
System.out.printf("== 高度: %d\n", AVLT.height());
if(AVLT.contains(5)){
System.out.println("I am here");
}
if(!AVLT.contains(8))
System.out.println("I am not here");
System.out.println(AVLT.findMax()+"");
System.out.println(AVLT.findMin()+"");
AVLT.remove(2);
AVLT.printTree();
System.out.println();
}
}
</pre><pre name="code" class="java">