0 课程地址
https://coding.imooc.com/lesson/207.html#mid=15212
1 重点关注
1.1 红黑树,avl,BST的使用场景
完全随机的数据,BST就可以
有顺序的数据查询较多,avl优先
有顺序的数据增删较多,红黑树优先
综合增删改查所有操作,红黑树优先
1.2 为什么和avl相比,红黑树增删更快,查询更慢
红黑树增删一次元素,最多通过两次旋转和一次颜色翻转即可实现(参见13-7).而avl增删元素,可能需要多次旋转维护平衡因子(参见12章)
而查询,avl是log(n)级别,而红黑树是2log(n)级别,所以avl更快
参考:https://coding.m.imooc.com/questiondetail.html?qid=81004
1.3 java中常用的封装好的RBTree,AVL,及BST
Java 标准库中的 TreeSet 就是基于红黑树实现的 Set,TreeMap 就是基于红黑树实现的 Map。Java 标准库中没有普通的二分搜索树和 AVL 树
2 课程内容
3 Coding(由于性能差异并不是太明显,故只放代码)
3.1 BST,RBTree,AVL对随机数的查询对比
测试类:
import java.util.ArrayList; public class Main { public static void main(String[] args) { System.out.println("Pride and Prejudice"); ArrayList<String> words = new ArrayList<>(); if(FileOperation.readFile("pride-and-prejudice.txt", words)) { System.out.println("Total words: " + words.size()); // Collections.sort(words); // Test BST long startTime = System.nanoTime(); BST<String, Integer> bst = new BST<>(); for (String word : words) { if (bst.contains(word)) bst.set(word, bst.get(word) + 1); else bst.add(word, 1); } for(String word: words) bst.contains(word); long endTime = System.nanoTime(); double time = (endTime - startTime) / 1000000000.0; System.out.println("BST: " + time + " s"); // Test AVL startTime = System.nanoTime(); AVLTree<String, Integer> avl = new AVLTree<>(); for (String word : words) { if (avl.contains(word)) avl.set(word, avl.get(word) + 1); else avl.add(word, 1); } for(String word: words) avl.contains(word); endTime = System.nanoTime(); time = (endTime - startTime) / 1000000000.0; System.out.println("AVL: " + time + " s"); // Test RBTree startTime = System.nanoTime(); RBTree<String, Integer> rbt = new RBTree<>(); for (String word : words) { if (rbt.contains(word)) rbt.set(word, rbt.get(word) + 1); else rbt.add(word, 1); } for(String word: words) rbt.contains(word); endTime = System.nanoTime(); time = (endTime - startTime) / 1000000000.0; System.out.println("RBTree: " + time + " s"); } System.out.println(); } }
3.2 BST,RBTree,AVL对随机数的增删操作对比
import java.util.ArrayList; import java.util.Random; public class Main2 { public static void main(String[] args) { // int n = 20000000; int n = 20000000; Random random = new Random(n); ArrayList<Integer> testData = new ArrayList<>(n); for(int i = 0 ; i < n ; i ++) testData.add(random.nextInt(Integer.MAX_VALUE)); // Test BST long startTime = System.nanoTime(); BST<Integer, Integer> bst = new BST<>(); for (Integer x: testData) bst.add(x, null); long endTime = System.nanoTime(); double time = (endTime - startTime) / 1000000000.0; System.out.println("BST: " + time + " s"); // Test AVL startTime = System.nanoTime(); AVLTree<Integer, Integer> avl = new AVLTree<>(); for (Integer x: testData) avl.add(x, null); endTime = System.nanoTime(); time = (endTime - startTime) / 1000000000.0; System.out.println("AVL: " + time + " s"); // Test RBTree startTime = System.nanoTime(); RBTree<Integer, Integer> rbt = new RBTree<>(); for (Integer x: testData) rbt.add(x, null); endTime = System.nanoTime(); time = (endTime - startTime) / 1000000000.0; System.out.println("RBTree: " + time + " s"); } }
3.3 RBTree,AVL对顺序数列的增删操作对比
import java.util.ArrayList; import java.util.Random; public class Main3 { public static void main(String[] args) { int n = 20000000; ArrayList<Integer> testData = new ArrayList<>(n); for(int i = 0 ; i < n ; i ++) testData.add(i); // Test AVL long startTime = System.nanoTime(); AVLTree<Integer, Integer> avl = new AVLTree<>(); for (Integer x: testData) avl.add(x, null); long endTime = System.nanoTime(); double time = (endTime - startTime) / 1000000000.0; System.out.println("AVL: " + time + " s"); // Test RBTree startTime = System.nanoTime(); RBTree<Integer, Integer> rbt = new RBTree<>(); for (Integer x: testData) rbt.add(x, null); endTime = System.nanoTime(); time = (endTime - startTime) / 1000000000.0; System.out.println("RBTree: " + time + " s"); } }
诸葛