0 课程地址
https://coding.imooc.com/lesson/207.html#mid=14353
1 重点关注
1.1 本节要点
基于avl树的map和set实现及性能测试
2 课程内容
2.1 性能测试
见3.1和3.2
3 Coding
3.1 coding Set的avl树实现及性能测试
案例:傲慢与偏见 统计单词
- 关键代码
public static void main(String[] args) { String fileName = "pride-and-prejudice.txt"; Double time1 = getTime(new BSTSet(),fileName); System.out.println("Main->getTime->end1->:"+time1); Double time2 = getTime(new LinkedListSet(),fileName); System.out.println("Main->getTime->end2->:"+time2); Double time3 = getTime(new AVLSet(),fileName); System.out.println("Main->getTime->end3->:"+time3); }
- 主类AVLTree:
package com.company;
import java.util.ArrayList;
import java.util.List;
public class AVLTree<K extends Comparable<K>,V> {
//1 定义Node
class Node{
private K key;
private V value;
private Node left,right;
private int height;
public Node(K key, V value){
this.key = key;
this.value = value;
this.left = null;
this.right = null;
this.height = 1;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Node{");
sb.append("key=").append(key);
sb.append(", value=").append(value);
sb.append('}');
return sb.toString();
}
}
//2 定义属性
private int size;
private Node root;
/**
* getHeight
* @author weidoudou
* @date 2023/4/1 11:34
* @param node 请添加参数描述
* @return int
**/
private int getHeight(Node node){
if(null==node){
return 0;
}
return node.height;
}
/**
* getBalanceFactor
* @author weidoudou
* @date 2023/4/1 11:36
* @param node 请添加参数描述
* @return int
**/
private int getBalanceFactor(Node node){
if(null==node){
return 0;
}
return getHeight(node.left) - getHeight(node.right);
}
/**
* 无参构造函数
* @author weidoudou
* @date 2023/1/1 11:09
* @return null
**/
public AVLTree(){
this.size = 0;
this.root = null;
}
public boolean isEmpty() {
return size==0?true:false;
}
public int getSize() {
return size;
}
//3 定义包含函数
private Node containsKey(K key,Node node){
//结束条件
if(null==node){
return null;
}
//循环条件
if(key.compareTo(node.key)<0){
return containsKey(key,node.left);
}else if(key.compareTo(node.key)>0){
return containsKey(key, node.right);
}else{//key.compareTo(node.key)=0 其实这个也是结束条件
return node;
}
}
public boolean contains(K key) {
return containsKey(key,root)==null?false:true;
}
public V get(K key) {
Node node = containsKey(key,root);
if(null!=node){
return node.value;
}
return null;
}
//3 递归,添加元素
public Node add(K key,V value,Node node){
//3.1 终止条件
//3.1.1 要插入的元素和二叉树原有节点相同,这个不用判断,因为已经调了containsKey方法判断了
if(node==null){
size++;
return new Node(key,value);
}
//3.1.2 最终插入左孩子
if(key.compareTo(node.key)<0 ){
node.left = add(key,value,node.left);
}else if(key.compareTo(node.key)>0){
node.right = add(key,value,node.right);
}else{
node.value = value;
}
node.height = 1+Math.max(getHeight(node.left),getHeight(node.right));
int balanceFactor = getBalanceFactor(node);
/*if(Math.abs(balanceFactor)>1){
System.out.println("unbalanced:"+balanceFactor);
}*/
//左左情况
if(balanceFactor>1&&getBalanceFactor(node.left)>=0){
return rightRotate(node);
//右右情况
}else if(balanceFactor<-1&&getBalanceFactor(node.right)<=0){
return leftRotate(node);
//左右情况
}else if(balanceFactor>1&&getBalanceFactor(node.left)<0){
//先对左子节点左旋转,然后整体右旋转
node.left = leftRotate(node.left);
return rightRotate(node);
//右左情况
}else if(balanceFactor<-1&&getBalanceFactor(node.right)>0){
node.right = rightRotate(node.right);
return leftRotate(node);
}
return node;
}
// 对节点y进行向右旋转操作,返回旋转后新的根节点x
// y x
// / \ / \
// x T4 向右旋转 (y) z y
// / \ - - - - - - - -> / \ / \
// z T3 T1 T2 T3 T4
// / \
// T1 T2