├── .gitignore ├── README.md ├── SUMMARY.md ├── images └── book-logo.PNG ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── waylau │ │ └── java │ │ └── demo │ │ ├── ForkJoinPoolDemo.java │ │ ├── HelloWorld.java │ │ ├── algorithm │ │ ├── Ant.java │ │ ├── AntColonyOptimization.java │ │ ├── BinarySearch.java │ │ ├── Chromosome.java │ │ ├── Fibonacci.java │ │ ├── FibonacciDemo.java │ │ ├── FibonacciSequenceBasic.java │ │ ├── FibonacciSequenceForwardCalculation.java │ │ ├── FibonacciSequenceWithCache.java │ │ ├── GeneticAlgorithm.java │ │ ├── GeneticAlgorithmMaxValue.java │ │ ├── GraphColoringProblem.java │ │ ├── GreedyAlgorithm.java │ │ ├── MapReduce.java │ │ ├── MapReduceDemo.java │ │ ├── MergeSort.java │ │ ├── NQueens.java │ │ └── QuickSort.java │ │ ├── datastructure │ │ ├── ArrayBinaryTree.java │ │ ├── ArrayBlockingQueueDemo.java │ │ ├── ArrayDemo.java │ │ ├── ArrayPriorityQueue.java │ │ ├── AvlNode.java │ │ ├── AvlTree.java │ │ ├── BinarySearchTree.java │ │ ├── BinaryTreeNode.java │ │ ├── ConcurrentSkipListMapDemo.java │ │ ├── Consumer.java │ │ ├── GomokuGame.java │ │ ├── Graph.java │ │ ├── GraphAStar.java │ │ ├── GraphBreadthFirstTraversal.java │ │ ├── GraphDepthFirstTraversal.java │ │ ├── GraphDijkstra.java │ │ ├── GraphFloydWarshall.java │ │ ├── GraphKruskal.java │ │ ├── GraphPrim.java │ │ ├── HashMapDemo.java │ │ ├── HeapPriorityQueue.java │ │ ├── Hero.java │ │ ├── HuffmanTree.java │ │ ├── HuffmanTreeNode.java │ │ ├── LinkedBinarySearchTree.java │ │ ├── LinkedBinaryTree.java │ │ ├── LinkedBlockingQueueDemo.java │ │ ├── List.java │ │ ├── ListDemo.java │ │ ├── MatrixDemo.java │ │ ├── MatrixUtil.java │ │ ├── PriorityQueue.java │ │ ├── Producer.java │ │ ├── QueueDemo.java │ │ ├── SequentialList.java │ │ ├── SequentialListStack.java │ │ ├── SinglyLinkedCircularList.java │ │ ├── SinglyLinkedList.java │ │ ├── SinglyLinkedListStack.java │ │ ├── Stack.java │ │ ├── StackDemo.java │ │ ├── StreamDemo.java │ │ └── TextCompressionWithMapDemo.java │ │ ├── hannotta │ │ ├── App.java │ │ ├── AutoMoveDisc.java │ │ ├── Disc.java │ │ ├── Hannotta.java │ │ ├── HannottaWindow.java │ │ ├── MenuTypeEnum.java │ │ ├── MouseHandler.java │ │ ├── Tower.java │ │ └── TowerPoint.java │ │ └── studentinfo │ │ ├── Student.java │ │ ├── StudentInfoManageSystem.java │ │ └── StudentInfoManageSystemDemo.java └── resources │ └── att48.tsp └── test └── java └── com └── waylau └── java └── demo ├── HelloWorldTests.java ├── algorithm ├── AntColonyOptimizationTest.java ├── BinarySearchTests.java ├── FibonacciSequenceBasicTests.java ├── FibonacciSequenceForwarCalculationTests.java ├── FibonacciSequenceWithCacheTests.java ├── GeneticAlgorithmMaxValueTest.java ├── GraphColoringProblemTests.java ├── GreedyAlgorithmTests.java ├── MergeSortTests.java ├── NQueensTests.java └── QuickSortTests.java ├── datastructure ├── ArrayBinaryTreeTest.java ├── ArrayBlockingQueueTests.java ├── ArrayDequeTests.java ├── ArrayListTests.java ├── ArrayPriorityQueueTest.java ├── ArrayTests.java ├── AvlTreeTest.java ├── ConcurrentSkipListMapTests.java ├── DictionaryTests.java ├── GraphAStarTests.java ├── GraphBreadthFirstTraversalTests.java ├── GraphDepthFirstTraversalTests.java ├── GraphDijkstraTests.java ├── GraphFloydWarshallTests.java ├── GraphKruskalTests.java ├── GraphPrimTests.java ├── HashMapTests.java ├── HeapPriorityQueueTest.java ├── HuffmanTreeTest.java ├── LinkedBinarySearchTreeTests.java ├── LinkedBinaryTreeTest.java ├── LinkedBlockingQueueTests.java ├── LinkedListTests.java ├── SequentialListStackTests.java ├── SequentialListTests.java ├── SinglyLinkedCircularListTests.java ├── SinglyLinkedListStackTests.java ├── SinglyLinkedListTests.java └── VectorTests.java └── hannotta └── HannottaTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.idea/ 3 | /.settings/ 4 | .classpath 5 | .project 6 | *.iml# Compiled class file 7 | *.class 8 | 9 | # Log file 10 | *.log 11 | 12 | # BlueJ files 13 | *.ctxt 14 | 15 | # Mobile Tools for Java (J2ME) 16 | .mtj.tmp/ 17 | 18 | # Package Files # 19 | *.jar 20 | *.war 21 | *.nar 22 | *.ear 23 | *.zip 24 | *.tar.gz 25 | *.rar 26 | 27 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 28 | hs_err_pid* 29 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | 第1章 绪论 1 2 | 1.1 引言 2 3 | 1.1.1 数据结构概述 2 4 | 1.1.2 什么是算法 5 5 | 1.1.3 算法的描述 5 6 | 1.2 程序的性能 9 7 | 1.2.1 程序的性能 9 8 | 1.2.2 程序的性能 10 9 | 1.3 渐近记法 12 10 | 1.3.1 大O标记法 12 11 | 1.3.2 大Ω标记法 12 12 | 1.3.3 大Θ标记法 13 13 | 1.3.4 渐近记法总结 13 14 | 1.4 算法复杂度等级及其分析 13 15 | 1.4.1 常数的时间复杂度O(1) 14 16 | 1.4.2 对数的时间复杂度O(logn) 14 17 | 1.4.3 线性的时间复杂度O(n) 15 18 | 1.4.4 平方的时间复杂度O(n2) 16 19 | 1.4.5 指数的时间复杂度O(2n) 16 20 | 1.4.6 算法复杂度总结 17 21 | 1.5 总结 17 22 | 1.6 习题 18 23 | 第2章 开发环境搭建及测试 19 24 | 2.1 安装JDK 20 25 | 2.1.1 解压.zip文件到指定位置 20 26 | 2.1.2 设置环境变量 20 27 | 2.1.3 验证安装 21 28 | 2.2 安装Maven 22 29 | 2.2.1 安装 22 30 | 2.2.2 设置本地仓库 22 31 | 2.2.3 设置镜像 23 32 | 2.3 安装IDE 23 33 | 2.3.1 解压.zip文件到指定位置 23 34 | 2.3.2 配置工作区间 24 35 | 2.3.3 配置JDK 24 36 | 2.3.4 配置Maven 24 37 | 2.3.5 设置字符编码 26 38 | 2.4 实战:编写单元测试用例 26 39 | 2.4.1 创建HelloWorld类 26 40 | 2.4.2 使用JUnit5 27 41 | 2.4.3 编写JUnit5测试用例 27 42 | 2.5 总结 29 43 | 2.6 习题 29 44 | 第3章 顺序表 30 45 | 3.1 Java数组初探 31 46 | 3.2 线性表数据结构 32 47 | 3.3 实战:使用数组实现顺序表 48 |    SequentialList 37 49 | 3.4 顺序表的动态扩容 47 50 | 3.4.1 顺序表的动态扩容原理 47 51 | 3.4.2 动态扩容机制的选择 48 52 | 3.4.3 ArrayList动态扩容分析 49 53 | 3.4.4 Vector动态扩容分析 50 54 | 3.4.5 选择ArrayList还是Vector 52 55 | 3.5 总结 52 56 | 3.6 习题 52 57 | 第4章 链表 53 58 | 第5章 数组和矩阵 93 59 | 第6章 栈 114 60 | 6.1 基本概念及应用场景 115 61 | 6.1.1 栈的基本概念 115 62 | 6.1.2 栈的应用场景 115 63 | 6.2 抽象数据类型 117 64 | 6.3 数组描述 117 65 | 6.4 实战:使用数组实现栈 66 |    SequentialListStack 117 67 | 6.4.1 成员变量及构造函数 117 68 | 6.4.2 统计栈的规模 118 69 | 6.4.3 判断栈中的数据元素是否为空 118 70 | 6.4.4 入栈 118 71 | 6.4.5 出栈 119 72 | 6.4.6 引用栈顶对象 119 73 | 6.4.7 时间复杂度分析总结 119 74 | 6.4.8 单元测试 119 75 | 6.5 链表描述 121 76 | 6.6 实战:使用链表实现栈 77 |    SinglyLinkedListStack 122 78 | 6.6.1 成员变量及构造函数 122 79 | 6.6.2 统计栈的规模 122 80 | 6.6.3 判断栈中的数据元素是否为空 122 81 | 6.6.4 入栈 123 82 | 6.6.5 出栈 123 83 | 6.6.6 引用栈顶对象 123 84 | 6.6.7 时间复杂度分析总结 123 85 | 6.6.8 单元测试 123 86 | 6.7 总结 125 87 | 6.8 习题 125 88 | 第7章 队列 126 89 | 第8章 跳表和散列 183 90 | 8.1 字典 184 91 | 8.1.1 跳表 184 92 | 8.1.2 散列 185 93 | 8.2 抽象数据类型 186 94 | 8.2.1 Dictionary抽象类 186 95 | 8.2.2 Map接口 187 96 | 8.2.3 Dictionary抽象类和Map接口 97 |    的抉择 194 98 | 8.3 散列HashMap 194 99 | 8.3.1 HashMap的声明 195 100 | 8.3.2 HashMap的成员变量和构造 101 |    函数 201 102 | 8.3.3 HashMap的核心方法 203 103 | 8.3.4 实战:HashMap的单元测试 210 104 | 8.3.5 实战:HashMap的应用案例 105 |    ——词频统计 214 106 | 107 | 8.4 基于跳表实现的 108 |    ConcurrentSkipListMap 216 109 | 8.4.1 ConcurrentSkipListMap的声明 216 110 | 8.4.2 ConcurrentSkipListMap的成员 111 |    变量和构造函数 217 112 | 8.4.3 ConcurrentSkipListMap的核心 113 |    方法 219 114 | 8.4.4 实战:ConcurrentSkipListMap 115 |    的单元测试 232 116 | 8.4.5 实战:ConcurrentSkipListMap 117 |    的应用案例——词频统计 235 118 | 8.5 实战:文本压缩 237 119 | 8.5.1 文本的压缩和解压 238 120 | 8.5.2 文本的压缩和解压的实现 238 121 | 8.5.3 测试文本的压缩和解压 240 122 | 8.6 总结 242 123 | 8.7 习题 243 124 | 第9章 树及二叉树 244 125 | 9.10 习题 272 126 | 第10章 优先级队列及堆 273 127 | 10.1 基本概念及应用场景 274 128 | 10.2 抽象数据类型 274 129 | 10.3 数组描述 274 130 | 10.4 实战:使用数组实现优先级队列 275 131 | 10.4.1 定义实现类 275 132 | 10.4.2 实现插入 276 133 | 10.4.3 实现删除 278 134 | 10.4.4 单元测试 279 135 | 10.5 堆描述 282 136 | 10.5.1 堆的定义 283 137 | 10.5.2 堆和普通树的区别 283 138 | 10.5.3 堆的存储 284 139 | 10.5.4 堆的常用操作 284 140 | 10.6 实战:使用堆实现优先级队列 285 141 | 10.6.1 定义实现类 286 142 | 10.6.2 实现插入 287 143 | 10.6.3 实现删除 289 144 | 10.6.4 单元测试 291 145 | 10.7 总结 293 146 | 10.8 习题 294 147 | 第11章 二叉查找树 295 148 | 第12章 平衡查找树 311 149 | 第13章 图 361 150 | 第14章 分而治之 438 151 | 第15章 贪心算法 461 152 | 第16章 动态规划 473 153 | 第17章 回溯 490 154 | 第18章 遗传算法 502 155 | 第19章 蚂蚁算法 528 156 | 第20章 汉诺塔游戏 555 157 | 20.1 实战:汉诺塔问题 556 158 | 参考文献 582 -------------------------------------------------------------------------------- /images/book-logo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waylau/java-data-structures-and-algorithms-in-action/cb0ac30192305da78a75edce9400c108fc996dd9/images/book-logo.PNG -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.waylau 7 | java-data-structures-and-algorithms-in-action 8 | 1.0.0 9 | jar 10 | 11 | java-data-structures-and-algorithms-in-action 12 | https://waylau.com 13 | 14 | 15 | UTF-8 16 | 14 17 | ${maven.compiler.source} 18 | 3.8.1 19 | 2.22.2 20 | 2.22.2 21 | 5.6.2 22 | 23 | 24 | 25 | 26 | maven-compiler-plugin 27 | ${maven-compiler-plugin.version} 28 | 29 | 30 | maven-surefire-plugin 31 | ${maven-surefire-plugin.version} 32 | 33 | 34 | maven-failsafe-plugin 35 | ${maven-failsafe-plugin.version} 36 | 37 | 38 | 39 | 40 | 41 | org.junit.jupiter 42 | junit-jupiter 43 | ${junit-jupiter.version} 44 | test 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/ForkJoinPoolDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.concurrent.ForkJoinPool; 9 | import java.util.concurrent.RecursiveTask; 10 | 11 | /** 12 | * 大数据处理示例. 13 | * 14 | * @since 1.0.0 2020年11月11日 15 | * @author Way Lau 16 | */ 17 | 18 | class Task extends RecursiveTask { 19 | private static final long serialVersionUID = 1L; 20 | 21 | final static int THRESHOLD = 4; 22 | private List dataList; 23 | 24 | public Task(List dataList) { 25 | this.dataList = dataList; 26 | } 27 | 28 | @Override 29 | protected Integer compute() { 30 | int length = dataList.size(); 31 | int count = 0; 32 | 33 | // 小于预设阀值就直接计算;否则划分子任务 34 | if (length < THRESHOLD) { // 直接计算 35 | 36 | for (int data : dataList) { 37 | // 能被3整除 38 | if (data % 3 == 0) { 39 | count++; 40 | } 41 | } 42 | 43 | } else { // 分而治之 44 | int split = length / 2; 45 | 46 | invokeAll( 47 | new Task( 48 | dataList.subList(0, split)), 49 | new Task(dataList.subList(split, 50 | length))); 51 | } 52 | 53 | return count; 54 | } 55 | 56 | 57 | /** 58 | * @param args 59 | */ 60 | public static void main(String[] args) { 61 | // 模拟50W的数据 62 | List dataList = new ArrayList<>(500000); 63 | for (int i = 0; i < 500000; i++) { 64 | dataList.add(i); 65 | } 66 | 67 | ForkJoinPool pool = new ForkJoinPool(); 68 | Integer result = pool.invoke(new Task(dataList)); 69 | 70 | System.out.println("result:" + result); 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/HelloWorld.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo; 5 | 6 | /** 7 | * Hello World. 8 | * 9 | * @since 1.0.0 2020年4月12日 10 | * @author Way Lau 11 | */ 12 | public class HelloWorld { 13 | 14 | private String words; 15 | 16 | public HelloWorld(String words) { 17 | this.words = words; 18 | } 19 | 20 | public String getWords() { 21 | return words; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/BinarySearch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * Binary Search. 8 | * 9 | *

10 | * Worst-case performance O(log n)
11 | * Best-case performance O(1)
12 | * Average performance O(log n)
13 | * Worst-case space complexity O(1)
14 | *

15 | * 16 | * @since 1.0.0 2020年11月27日 17 | * @author Way Lau 18 | */ 19 | 20 | public class BinarySearch> { 21 | 22 | /** 23 | * 值在数组中的索引 24 | * 25 | * @param value 待查找的值 26 | * @param array 假定数组已排序 27 | * 28 | * @return 值在数组中的索引 29 | */ 30 | public static final int find(T value, T[] array) { 31 | return recursiveFind(array, value, 0, 32 | array.length - 1); 33 | } 34 | 35 | // 递归查找元素 36 | @SuppressWarnings("unchecked") 37 | private static int recursiveFind(T[] array, T value, 38 | int start, int end) { 39 | if (start == end) { 40 | T lastValue = array[start]; // start==end 41 | 42 | if (value == lastValue) { 43 | return start; // start==end 44 | } 45 | 46 | return Integer.MAX_VALUE; 47 | } 48 | 49 | final int low = start; 50 | final int high = end + 1; // 索引是从0开始的,所以加一个 51 | final int middle = low + ((high - low) / 2); // 取中间索引 52 | final T middleValue = array[middle]; 53 | 54 | // 与中间值进行比较 55 | int compareResult = ((Comparable) value) 56 | .compareTo(middleValue); 57 | 58 | if (compareResult == 0) { // 等于中间值,则查找结束 59 | return middle; 60 | } else if (compareResult > 0) {// 大于中间值,则往右查找 61 | return recursiveFind(array, value, middle + 1, 62 | end); 63 | } else {// 小于中间值,则往左查找 64 | return recursiveFind(array, value, start, 65 | middle - 1); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/Chromosome.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import java.util.ArrayList; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Chromosome. 12 | * 13 | * @author Way Lau 14 | * @since 2020-11-30 15 | */ 16 | 17 | public class Chromosome { 18 | private boolean[] genes;// 基因序列 19 | 20 | private double score;// 对应的函数得分 21 | 22 | public double getScore() { 23 | return score; 24 | } 25 | 26 | public void setScore(double score) { 27 | this.score = score; 28 | } 29 | 30 | /** 31 | * 限制无参构造函数的使用 32 | */ 33 | private Chromosome() { 34 | } 35 | 36 | /** 37 | * 随机生成基因序列 38 | * 39 | * @param size 基因序列长度 40 | */ 41 | public Chromosome(int size) { 42 | if (size <= 0) { 43 | return; 44 | } 45 | 46 | initGeneSize(size); 47 | 48 | for (int i = 0; i < size; i++) { 49 | genes[i] = Math.random() >= 0.5; 50 | } 51 | } 52 | 53 | /** 54 | * 初始化基因长度 55 | * 56 | * @param size 基因序列长度 57 | */ 58 | private void initGeneSize(int size) { 59 | if (size <= 0) { 60 | return; 61 | } 62 | 63 | genes = new boolean[size]; 64 | } 65 | 66 | /** 67 | * 将基因转化为对应的数字 68 | * 69 | * @return 基因转化成应的数字 70 | */ 71 | public int getNum() { 72 | if (genes == null) { 73 | return 0; 74 | } 75 | 76 | int num = 0; 77 | 78 | for (boolean bool : genes) { 79 | num <<= 1; 80 | if (bool) { 81 | num += 1; 82 | } 83 | } 84 | 85 | return num; 86 | } 87 | 88 | /** 89 | * 基因num个位置发生变异 90 | * 91 | * @param num 突变的位置 92 | */ 93 | public void mutation(int num) { 94 | // 允许变异 95 | int size = genes.length; 96 | 97 | for (int i = 0; i < num; i++) { 98 | // 寻找变异位置 99 | int at = ((int) (Math.random() * size)) % size; 100 | 101 | // 变异后的值 102 | boolean bool = !genes[at]; 103 | genes[at] = bool; 104 | } 105 | } 106 | 107 | /** 108 | * 克隆染色体 109 | * 110 | * @param c 被克隆染色体 111 | * 112 | * @return 克隆染色体 113 | */ 114 | public static Chromosome clone(final Chromosome c) { 115 | if (c == null || c.genes == null) { 116 | return null; 117 | } 118 | 119 | Chromosome clonedChromosome = new Chromosome(); 120 | clonedChromosome.initGeneSize(c.genes.length); 121 | 122 | for (int i = 0; i < c.genes.length; i++) { 123 | clonedChromosome.genes[i] = c.genes[i]; 124 | } 125 | 126 | return clonedChromosome; 127 | } 128 | 129 | /** 130 | * 遗传产生下一代染色体 131 | * 132 | * @param c1 133 | * @param c2 134 | */ 135 | public static List genetic(Chromosome p1, 136 | Chromosome p2) { 137 | if (p1 == null || p2 == null) { // 染色体有一个为空,不产生下一代 138 | return null; 139 | } 140 | 141 | if (p1.genes == null || p2.genes == null) { // 染色体有一个没有基因序列,不产生下一代 142 | return null; 143 | } 144 | 145 | if (p1.genes.length != p2.genes.length) { // 染色体基因序列长度不同,不产生下一代 146 | return null; 147 | } 148 | 149 | Chromosome c1 = clone(p1); 150 | Chromosome c2 = clone(p2); 151 | 152 | // 随机产生交叉互换位置 153 | int size = c1.genes.length; 154 | int a = ((int) (Math.random() * size)) % size; 155 | int b = ((int) (Math.random() * size)) % size; 156 | int min = a > b ? b : a; 157 | int max = a > b ? a : b; 158 | 159 | // 对位置上的基因进行交叉互换 160 | for (int i = min; i <= max; i++) { 161 | boolean t = c1.genes[i]; 162 | c1.genes[i] = c2.genes[i]; 163 | c2.genes[i] = t; 164 | } 165 | 166 | List list = new ArrayList(); 167 | 168 | list.add(c1); 169 | list.add(c2); 170 | 171 | return list; 172 | } 173 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/Fibonacci.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import java.util.concurrent.RecursiveTask; 7 | 8 | /** 9 | * Fibonacci 10 | * 11 | * @since 1.0.0 2020年11月27日 12 | * @author Way Lau 13 | */ 14 | public class Fibonacci extends RecursiveTask { 15 | private static final long serialVersionUID = 1L; 16 | 17 | final int n; 18 | 19 | Fibonacci(int n) { 20 | this.n = n; 21 | } 22 | 23 | protected Integer compute() { 24 | if (n <= 1) { 25 | return n; 26 | } 27 | 28 | Fibonacci f1 = new Fibonacci(n - 1); 29 | 30 | // 创建子任务 31 | f1.fork(); 32 | Fibonacci f2 = new Fibonacci(n - 2); 33 | 34 | // 等待子任务结果,并合并结果 35 | return f2.compute() + f1.join(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/FibonacciDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import java.util.concurrent.ForkJoinPool; 7 | 8 | /** 9 | * Fibonacci Demo. 10 | * 11 | * @since 1.0.0 2020年11月27日 12 | * @author Way Lau 13 | */ 14 | public class FibonacciDemo { 15 | 16 | /** 17 | * @param args 18 | */ 19 | public static void main(String[] args) { 20 | // 创建分治任务线程池 21 | ForkJoinPool fjp = new ForkJoinPool(4); 22 | 23 | // 创建分治任务 24 | Fibonacci fib = new Fibonacci(30); 25 | 26 | // 启动分治任务 27 | Integer result = fjp.invoke(fib); 28 | 29 | // 输出结果 30 | System.out.println(result); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/FibonacciSequenceBasic.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * Fibonacci Sequence. 8 | * 9 | * @since 1.0.0 2020年11月28日 10 | * @author Way Lau 11 | */ 12 | public class FibonacciSequenceBasic { 13 | 14 | public static int fibonacci(int n) { 15 | 16 | if ((n == 1) || (n == 2)) { 17 | return 1; 18 | } 19 | 20 | // 递归 21 | return fibonacci(n - 1) + fibonacci(n - 2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/FibonacciSequenceForwardCalculation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * Fibonacci Sequence Forward Calculation 8 | * 9 | * @since 1.0.0 2020年11月28日 10 | * @author Way Lau 11 | */ 12 | public class FibonacciSequenceForwardCalculation { 13 | public static int fibonacci(int n) { 14 | if ((n == 1) || (n == 2)) { 15 | return 1; 16 | } 17 | 18 | int fn = 0; 19 | int fn1 = 1; 20 | int fn2 = 1; 21 | int k = 3; 22 | 23 | while (k <= n) { 24 | fn = fn1 + fn2; 25 | fn1 = fn2; 26 | fn2 = fn; 27 | k++; 28 | } 29 | 30 | return fn; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/FibonacciSequenceWithCache.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * Fibonacci Sequence with cache 8 | * 9 | * @since 1.0.0 2020年11月28日 10 | * @author Way Lau 11 | */ 12 | public class FibonacciSequenceWithCache { 13 | private static final int cache[] = new int[100000]; 14 | 15 | public static int fibonacci(int n) { 16 | if ((n == 1) || (n == 2)) { 17 | return 1; 18 | } else if (0 != cache[n]) { 19 | return cache[n]; 20 | } 21 | 22 | cache[n] = fibonacci(n - 1) + fibonacci(n - 2); 23 | 24 | return cache[n]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/GeneticAlgorithmMaxValue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * GeneticAlgorithmMaxValue. 8 | * 9 | * @since 1.0.0 2020年11月29日 10 | * @author Way Lau 11 | */ 12 | public class GeneticAlgorithmMaxValue 13 | extends GeneticAlgorithm { 14 | 15 | private final int num; 16 | 17 | /** 18 | * 构造函数 19 | * 20 | * @param geneSize 21 | */ 22 | public GeneticAlgorithmMaxValue(int geneSize) { 23 | super(geneSize); 24 | 25 | num = 1 << geneSize; 26 | } 27 | 28 | @Override 29 | public double changeX(Chromosome chro) { 30 | return ((1.0 * chro.getNum() / num) * 100) + 6; 31 | } 32 | 33 | @Override 34 | public double caculateY(double x) { 35 | return 100 - Math.log(x); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/GraphColoringProblem.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * Graph Coloring Problem. 8 | * 9 | * @author Way Lau 10 | * @since 2020-11-02 11 | */ 12 | public class GraphColoringProblem { 13 | /** 14 | * 图着色:
15 | * 16 | * @param graph 待着色图 17 | * @param n 图的结点数 18 | * @param m 限制需要涂的颜色种数 19 | * 20 | * @return 满足时返回图着色的结果,否则返回空 21 | */ 22 | public static int[] graphColor(int[][] graph, int n, 23 | int m) { 24 | if (m <= 0) { 25 | return null; 26 | } 27 | 28 | int[] color = initColor(n);// 初始化数组 29 | int index = 0; 30 | 31 | while (index >= 0) { 32 | color[index] += 1;// 填色 33 | 34 | while (color[index] <= m) { 35 | // 检验当前所涂颜色是否符合 36 | if (check(graph, color, index)) { 37 | break;// 符合 38 | } else { 39 | color[index] += 1;// 考察下一种颜色 40 | } 41 | } 42 | 43 | if (color[index] <= m && index == n - 1) { 44 | return color; 45 | } 46 | 47 | if (color[index] > m) { 48 | color[index--] = 0;// 回溯 49 | } else { 50 | index++;// 填下一个结点 51 | } 52 | } 53 | 54 | return null; 55 | } 56 | 57 | /** 58 | * 检测当前考察结点的颜色是否符合要求:
59 | * 60 | * @param graph 图 61 | * @param color 图的每个结点的颜色组成的数组 62 | * @param index 索引,用于考察当前结点的颜色是否符合 63 | * 64 | * @return 符合或者不符合 65 | */ 66 | public static boolean check(int[][] graph, int[] color, 67 | int index) { 68 | for (int i = 0; i < index; i++) { 69 | // 判断当前结点所图的颜色是否与前面重复 70 | 71 | if (graph[index][i] == 1 72 | && color[i] == color[index]) { 73 | return false; 74 | } 75 | } 76 | 77 | return true; 78 | } 79 | 80 | /** 81 | * 初始化颜色数组:
82 | * 83 | * @param n 结点的个数 84 | * @return 初始化后的数组 85 | */ 86 | 87 | public static int[] initColor(int n) { 88 | int[] color = new int[n]; 89 | 90 | for (int i = 0; i < n; i++) { 91 | color[i] = 0; 92 | } 93 | 94 | return color; 95 | } 96 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/GreedyAlgorithm.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Greedy Algorithm. 11 | * 12 | * @since 1.0.0 2020年11月28日 13 | * @author Way Lau 14 | */ 15 | public class GreedyAlgorithm { 16 | 17 | public static int maxNumber(int[] customers) { 18 | if (customers.length < 3) { 19 | return 0; 20 | } 21 | 22 | // 把符合条件的点餐员都取出来 23 | List dealers = new ArrayList<>(); 24 | 25 | for (int i = 1; i < customers.length - 1; i++) { 26 | if (customers[i - 1] < customers[i] 27 | && customers[i] > customers[i + 1]) { 28 | dealers.add(i); 29 | i++; 30 | } 31 | } 32 | 33 | // 初始化k为最大数 34 | int k = dealers.size(); 35 | 36 | // 等于1则直接返回 37 | if (k == 1) { 38 | return k; 39 | } 40 | 41 | // 大于1的时候进循环 42 | while (k >= 1) { 43 | // 记录合规的点餐员数量 44 | int passed = 1; 45 | for (int i = 0; i < dealers.size() - 1; i++) { 46 | if (dealers.get(i + 1) 47 | - dealers.get(i) >= k) { 48 | 49 | // 相邻两个间隔合规 50 | passed++; 51 | } else if (i < dealers.size() - 2 52 | && dealers.get(i + 2) 53 | - dealers.get(i) >= k) { 54 | // 如果相邻两个不合规,跳过一个看是否合规 55 | 56 | passed++; 57 | i++; 58 | } 59 | } 60 | 61 | // 如果合规个数等于k,则返回 62 | if (k == passed) { 63 | break; 64 | } 65 | 66 | // 否则k减小,再来一次 67 | k--; 68 | } 69 | 70 | return k; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/MapReduce.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.concurrent.RecursiveTask; 9 | 10 | /** 11 | * MapReduce 12 | * 13 | * @since 1.0.0 2020年11月27日 14 | * @author Way Lau 15 | */ 16 | public class MapReduce 17 | extends RecursiveTask> { 18 | private static final long serialVersionUID = 1L; 19 | 20 | private String[] fc; 21 | private int start, end; 22 | 23 | // 构造函数 24 | MapReduce(String[] fc, int fr, int to) { 25 | this.fc = fc; 26 | this.start = fr; 27 | this.end = to; 28 | } 29 | 30 | @Override 31 | protected Map compute() { 32 | if (end - start == 1) { 33 | return calc(fc[start]); 34 | } else { 35 | int mid = (start + end) / 2; 36 | MapReduce mr1 = new MapReduce(fc, start, mid); 37 | mr1.fork(); 38 | MapReduce mr2 = new MapReduce(fc, mid, end); 39 | 40 | // 计算子任务,并返回合并的结果 41 | return merge(mr2.compute(), mr1.join()); 42 | } 43 | } 44 | 45 | // 合并结果 46 | private Map merge(Map r1, 47 | Map r2) { 48 | Map result = new HashMap<>(); 49 | result.putAll(r1); 50 | 51 | // 合并结果 52 | r2.forEach((k, v) -> { 53 | Long c = result.get(k); 54 | if (c != null) { 55 | result.put(k, c + v); 56 | } else { 57 | result.put(k, v); 58 | } 59 | 60 | }); 61 | return result; 62 | } 63 | 64 | // 统计单词数量 65 | private Map calc(String line) { 66 | Map result = new HashMap<>(); 67 | 68 | // 分割单词 69 | String[] words = line.split("\\s+"); 70 | 71 | // 统计单词数量 72 | for (String w : words) { 73 | Long v = result.get(w); 74 | if (v != null) { 75 | result.put(w, v + 1); 76 | } else { 77 | result.put(w, 1L); 78 | } 79 | 80 | } 81 | return result; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/MapReduceDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import java.util.Map; 7 | import java.util.concurrent.ForkJoinPool; 8 | 9 | /** 10 | * @since 1.0.0 2020年11月27日 11 | * @author Way Lau 12 | */ 13 | public class MapReduceDemo { 14 | public static void main(String[] args) { 15 | String[] fc = { "hello world", "hello me", 16 | "hello fork", "hello join", 17 | "fork join in world" }; 18 | 19 | // 创建 ForkJoin 线程池 20 | ForkJoinPool fjp = new ForkJoinPool(3); 21 | 22 | // 创建任务 23 | MapReduce mr = new MapReduce(fc, 0, fc.length); 24 | 25 | // 启动任务 26 | Map result = fjp.invoke(mr); 27 | 28 | // 输出结果 29 | result.forEach( 30 | (k, v) -> System.out.println(k + ":" + v)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/MergeSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * Merge sort. 8 | *

9 | * Family: Merging.
10 | * Space: In-place.
11 | * Stable: True.
12 | *

13 | * Average case = O(n*log n)
14 | * Worst case = O(n*log n)
15 | * Best case = O(n*log n)
16 | *

17 | * 18 | * @since 1.0.0 2020年11月27日 19 | * @author Way Lau 20 | */ 21 | @SuppressWarnings("unchecked") 22 | public class MergeSort> { 23 | 24 | public static enum SPACE_TYPE { 25 | IN_PLACE, NOT_IN_PLACE 26 | } 27 | 28 | private MergeSort() { 29 | } 30 | 31 | public static > T[] sort( 32 | SPACE_TYPE type, T[] unsorted) { 33 | sort(type, 0, unsorted.length, unsorted); 34 | return unsorted; 35 | } 36 | 37 | private static > void sort( 38 | SPACE_TYPE type, int start, int length, 39 | T[] unsorted) { 40 | if (length > 2) { 41 | int aLength = (int) Math.floor(length / 2); 42 | int bLength = length - aLength; 43 | sort(type, start, aLength, unsorted); 44 | sort(type, start + aLength, bLength, unsorted); 45 | 46 | if (type == SPACE_TYPE.IN_PLACE) { 47 | mergeInPlace(start, aLength, 48 | start + aLength, bLength, unsorted); 49 | } else { 50 | mergeWithExtraStorage(start, aLength, 51 | start + aLength, bLength, unsorted); 52 | } 53 | } else if (length == 2) { 54 | T e = unsorted[start + 1]; 55 | 56 | if (e.compareTo(unsorted[start]) < 0) { 57 | unsorted[start + 1] = unsorted[start]; 58 | unsorted[start] = e; 59 | } 60 | } 61 | } 62 | 63 | private static > void mergeInPlace( 64 | int aStart, int aLength, int bStart, 65 | int bLength, T[] unsorted) { 66 | int i = aStart; 67 | int j = bStart; 68 | 69 | int aSize = aStart + aLength; 70 | int bSize = bStart + bLength; 71 | 72 | while (i < aSize && j < bSize) { 73 | T a = unsorted[i]; 74 | T b = unsorted[j]; 75 | 76 | if (b.compareTo(a) < 0) { 77 | // 把所有东西都移到正确的位置 78 | System.arraycopy(unsorted, i, unsorted, 79 | i + 1, j - i); 80 | unsorted[i] = b; 81 | i++; 82 | j++; 83 | aSize++; 84 | } else { 85 | i++; 86 | } 87 | } 88 | } 89 | 90 | private static > void mergeWithExtraStorage( 91 | int aStart, int aLength, int bStart, 92 | int bLength, T[] unsorted) { 93 | int count = 0; 94 | T[] output = (T[]) new Comparable[aLength 95 | + bLength]; 96 | int i = aStart; 97 | int j = bStart; 98 | 99 | int aSize = aStart + aLength; 100 | int bSize = bStart + bLength; 101 | 102 | while (i < aSize || j < bSize) { 103 | T a = null; 104 | if (i < aSize) { 105 | a = unsorted[i]; 106 | } 107 | 108 | T b = null; 109 | if (j < bSize) { 110 | b = unsorted[j]; 111 | } 112 | 113 | if (a != null && b == null) { 114 | output[count++] = a; 115 | i++; 116 | } else if (b != null && a == null) { 117 | output[count++] = b; 118 | j++; 119 | } else if (b != null && b.compareTo(a) <= 0) { 120 | output[count++] = b; 121 | j++; 122 | } else { 123 | output[count++] = a; 124 | i++; 125 | } 126 | } 127 | 128 | int x = 0; 129 | int size = aStart + aLength + bLength; 130 | 131 | for (int y = aStart; y < size; y++) { 132 | unsorted[y] = output[x++]; 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/NQueens.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.algorithm; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | /** 8 | * N Queens 9 | * 10 | * @author Way Lau 11 | * @since 2020-11-30 12 | */ 13 | public class NQueens { 14 | private static List> res = new LinkedList<>(); 15 | 16 | public static List> solveNQueens(int n) { 17 | char[][] board = new char[n][n]; 18 | 19 | for (int i = 0; i < n; i++) { 20 | Arrays.fill(board[i], '.'); 21 | } 22 | 23 | backtrack(0, board); 24 | 25 | return res; 26 | } 27 | 28 | /** 29 | * backtrack为标准的回溯法模板 30 | * 31 | * @param index 索引,或者已做选择的路径 32 | * @param board 33 | */ 34 | private static void backtrack(int index, 35 | char[][] board) { 36 | // 结束条件为所有的皇后都已放置 37 | if (index == board.length) { 38 | res.add(chars2StrList(board));// 把可行解加入到结果集 39 | 40 | return; 41 | } 42 | 43 | int cols = board[0].length; 44 | 45 | // 选择列表为每一列 46 | for (int i = 0; i < cols; i++) { 47 | if (!isValid(board, index, i)) {// 剪枝 48 | continue; 49 | } 50 | 51 | // 做选择,在当前位置放置皇后 52 | board[index][i] = 'Q'; 53 | 54 | // 向纵深方向扩展一步 55 | backtrack(index + 1, board); 56 | 57 | // 撤销选择 58 | board[index][i] = '.'; 59 | } 60 | } 61 | 62 | private static List chars2StrList( 63 | char[][] board) { 64 | List strList = new LinkedList<>(); 65 | 66 | for (char[] row : board) { 67 | strList.add(String.valueOf(row)); 68 | } 69 | 70 | return strList; 71 | } 72 | 73 | private static boolean isValid(char[][] board, int row, 74 | int col) { 75 | // 检查同一列有没有放置皇后 76 | for (int i = 0; i < row; i++) { 77 | if (board[i][col] == 'Q') { 78 | return false; 79 | } 80 | } 81 | 82 | // 检查左上角的对角线有没有放置皇后 83 | for (int i = row - 1, j = col - 1; i >= 0 84 | && j >= 0; i--, j--) { 85 | if (board[i][j] == 'Q') { 86 | return false; 87 | } 88 | } 89 | 90 | // 检查右上角的对角线有没有放置皇后 91 | for (int i = row - 1, j = col + 1; i >= 0 92 | && j < board.length; i--, j++) { 93 | if (board[i][j] == 'Q') { 94 | return false; 95 | } 96 | } 97 | 98 | return true; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/algorithm/QuickSort.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.algorithm; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * Quick sort. 7 | * 8 | *

9 | * Family: Divide and conquer.
10 | * Space: In-place.
11 | * Stable: False.
12 | *

13 | * 14 | * Average case = O(n*log n)
15 | * Worst case = O(n^2)
16 | * Best case = O(n) [three-way partition and equal keys]
17 | * 18 | *

19 | * 20 | * @author Way Lau 21 | * @since 2020-11-27 22 | */ 23 | public class QuickSort> { 24 | 25 | private static final Random RAND = new Random(); 26 | 27 | public static enum PIVOT_TYPE { 28 | FIRST, MIDDLE, RANDOM 29 | } 30 | 31 | public static PIVOT_TYPE type = PIVOT_TYPE.RANDOM; 32 | 33 | private QuickSort() { 34 | } 35 | 36 | public static > T[] sort( 37 | PIVOT_TYPE pivotType, T[] unsorted) { 38 | int pivot = 0; 39 | 40 | if (pivotType == PIVOT_TYPE.MIDDLE) { 41 | pivot = unsorted.length / 2; 42 | } else if (pivotType == PIVOT_TYPE.RANDOM) { 43 | pivot = getRandom(unsorted.length); 44 | } 45 | 46 | sort(pivot, 0, unsorted.length - 1, unsorted); 47 | 48 | return unsorted; 49 | } 50 | 51 | private static > void sort( 52 | int index, int start, int finish, 53 | T[] unsorted) { 54 | int pivotIndex = start + index; 55 | T pivot = unsorted[pivotIndex]; 56 | int s = start; 57 | int f = finish; 58 | 59 | while (s <= f) { 60 | while (unsorted[s].compareTo(pivot) < 0) { 61 | s++; 62 | } 63 | 64 | while (unsorted[f].compareTo(pivot) > 0) { 65 | f--; 66 | } 67 | 68 | if (s <= f) { 69 | swap(s, f, unsorted); 70 | s++; 71 | f--; 72 | } 73 | } 74 | 75 | if (start < f) { 76 | pivotIndex = getRandom((f - start) + 1); 77 | sort(pivotIndex, start, f, unsorted); 78 | } 79 | 80 | if (s < finish) { 81 | pivotIndex = getRandom((finish - s) + 1); 82 | sort(pivotIndex, s, finish, unsorted); 83 | } 84 | } 85 | 86 | private static final int getRandom(int length) { 87 | if (type == PIVOT_TYPE.RANDOM && length > 0) { 88 | return RAND.nextInt(length); 89 | } 90 | 91 | if (type == PIVOT_TYPE.FIRST && length > 0) { 92 | return 0; 93 | } 94 | 95 | return length / 2; 96 | } 97 | 98 | private static > void swap( 99 | int index1, int index2, T[] unsorted) { 100 | T index2Element = unsorted[index1]; 101 | unsorted[index1] = unsorted[index2]; 102 | unsorted[index2] = index2Element; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/ArrayBinaryTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * ArrayBinaryTree. 10 | * 11 | * @since 1.0.0 2020年8月12日 12 | * @author Way Lau 13 | */ 14 | public class ArrayBinaryTree { 15 | 16 | private T[] arr; 17 | 18 | public ArrayBinaryTree(T[] arr) { 19 | if (arr == null || arr.length == 0) { 20 | throw new IllegalArgumentException( 21 | "arr must not null"); 22 | } 23 | 24 | this.arr = arr; 25 | } 26 | 27 | // 前序遍历 28 | public void preOrder(int index, List result) { 29 | result.add(arr[index]); 30 | 31 | if (2 * index + 1 < arr.length) { 32 | preOrder(2 * index + 1, result); 33 | } 34 | 35 | if (2 * index + 2 < arr.length) { 36 | preOrder(2 * index + 2, result); 37 | } 38 | } 39 | 40 | // 中序遍历 41 | public void infixOrder(int index, List result) { 42 | if (2 * index + 1 < arr.length) { 43 | infixOrder(2 * index + 1, result); 44 | } 45 | 46 | result.add(arr[index]); 47 | 48 | if (2 * index + 2 < arr.length) { 49 | infixOrder(2 * index + 2, result); 50 | } 51 | } 52 | 53 | // 后序遍历 54 | public void postOrder(int index, List result) { 55 | if (2 * index + 1 < arr.length) { 56 | postOrder(2 * index + 1, result); 57 | } 58 | 59 | if (2 * index + 2 < arr.length) { 60 | postOrder(2 * index + 2, result); 61 | } 62 | 63 | result.add(arr[index]); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/ArrayBlockingQueueDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.concurrent.ArrayBlockingQueue; 7 | import java.util.concurrent.BlockingQueue; 8 | 9 | /** 10 | * ArrayBlockingQueue Demo 11 | * 12 | * @since 1.0.0 2020年5月3日 13 | * @author Way Lau 14 | */ 15 | class ArrayBlockingQueueDemo { 16 | 17 | public static void main(String[] args) { 18 | BlockingQueue queue = 19 | new ArrayBlockingQueue(3); 20 | 21 | // 1个生产者 22 | Producer p = new Producer(queue); 23 | 24 | // 2个消费者 25 | Consumer c1 = new Consumer("c1", queue); 26 | Consumer c2 = new Consumer("c2", queue); 27 | 28 | // 启动线程 29 | new Thread(p).start(); 30 | new Thread(c1).start(); 31 | new Thread(c2).start(); 32 | } 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/ArrayDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import com.waylau.java.demo.studentinfo.Student; 7 | 8 | /** 9 | * Array Demo. 10 | * 11 | * @since 1.0.0 2020年5月3日 12 | * @author Way Lau 13 | */ 14 | public class ArrayDemo { 15 | 16 | /** 17 | * @param args 18 | */ 19 | @SuppressWarnings("unused") 20 | public static void main(String[] args) { 21 | // 声明数组 22 | int[] anArray; 23 | 24 | // 分配内存空间 25 | anArray = new int[10]; 26 | 27 | // 初始化元素 28 | anArray[0] = 100; 29 | anArray[1] = 200; 30 | anArray[2] = 300; 31 | anArray[3] = 400; 32 | anArray[4] = 500; 33 | anArray[5] = 600; 34 | anArray[6] = 700; 35 | anArray[7] = 800; 36 | anArray[8] = 900; 37 | anArray[9] = 1000; 38 | // anArray[10] = 66666; // 错误!报java.lang.ArrayIndexOutOfBoundsException异常 39 | 40 | // 获取元素值 41 | System.out.println("Element at index 0: " + anArray[0]); 42 | System.out.println("Element at index 1: " + anArray[1]); 43 | System.out.println("Element at index 2: " + anArray[2]); 44 | System.out.println("Element at index 3: " + anArray[3]); 45 | System.out.println("Element at index 4: " + anArray[4]); 46 | System.out.println("Element at index 5: " + anArray[5]); 47 | System.out.println("Element at index 6: " + anArray[6]); 48 | System.out.println("Element at index 7: " + anArray[7]); 49 | System.out.println("Element at index 8: " + anArray[8]); 50 | System.out.println("Element at index 9: " + anArray[9]); 51 | System.out.println("Array length: " + anArray.length); 52 | 53 | // 基本数据类型 54 | int[] array = new int[] { 1, 2, 3, 4, 5 }; 55 | int[] intArray = { 1, 2, 3, 4, 5 }; 56 | double[] doubleArray = { 1.1D, 22.62D, 33.3D, 44.4D }; 57 | boolean[] booleanArray = { true, false }; 58 | char[] charArray = { 'd', 'e', 'w', 'a', 'y', 'f', 'e', 'd' }; 59 | String[] stringArray = { "C", "C++", "Java" }; 60 | 61 | // 复杂数据类型 62 | Student student1 = new Student(32, "Way Lau", "17088888888", "Shenzhen"); 63 | Student student2 = new Student(28, "Ken Sun", "17000000000", "Shenzhen"); 64 | Student[] studentArray = { student1, student2 }; 65 | 66 | // 数组的默认值 67 | // arrayDefault等效于arrayDefault2 68 | int[] arrayDefault = new int[5]; 69 | int[] arrayDefault2 = new int[] { 0, 0, 0, 0, 0 }; 70 | 71 | // 二维数组 72 | // 即创建了一个 3*2 的二维数组,array 里有三个数组元素,三个数组元素都是长度为 2 的一维数组的引用。 73 | int[][] twoDArray = new int[3][2]; 74 | 75 | // 二维数组相当于是一维数组这种引用类型的引用组成的 76 | // twoDArray2等价于twoDArray3 77 | int[][] twoDArray2 = new int[3][]; 78 | int[][] twoDArray3 = { null, null, null }; 79 | 80 | // 下面可以为 array 数组分别赋上长度不同的一维数组 81 | int[][] twoDArray4 = new int[3][]; 82 | twoDArray4[0] = new int[1]; 83 | twoDArray4[1] = new int[2]; 84 | twoDArray4[2] = new int[3]; 85 | 86 | int[][] twoDArray5 = { { 1, 2 }, { 1, 3, 5 }, { 2 } }; 87 | 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/ArrayPriorityQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.Arrays; 7 | import java.util.Comparator; 8 | 9 | /** 10 | * Array-based Priority Queue. 11 | * 12 | * @since 1.0.0 2020年9月14日 13 | * @author Way Lau 14 | */ 15 | public class ArrayPriorityQueue 16 | implements PriorityQueue { 17 | private static final int DEFAULT_INITIAL_CAPACITY = 11; 18 | 19 | private int size; 20 | 21 | private Object[] queue; 22 | 23 | private final Comparator comparator; 24 | 25 | public ArrayPriorityQueue() { 26 | this(DEFAULT_INITIAL_CAPACITY, null); 27 | } 28 | 29 | public ArrayPriorityQueue(int initialCapacity) { 30 | this(initialCapacity, null); 31 | } 32 | 33 | public ArrayPriorityQueue( 34 | Comparator comparator) { 35 | this(DEFAULT_INITIAL_CAPACITY, comparator); 36 | } 37 | 38 | public ArrayPriorityQueue(int initialCapacity, 39 | Comparator comparator) { 40 | if (initialCapacity < 1) { 41 | throw new IllegalArgumentException(); 42 | } 43 | 44 | this.queue = new Object[initialCapacity]; 45 | this.comparator = comparator; 46 | } 47 | 48 | @Override 49 | public boolean add(E e) { 50 | int i = size; 51 | 52 | // 判断容量,自动增长 53 | if (i >= queue.length) { 54 | grow(i + 1); 55 | } 56 | 57 | // 从新排序 58 | siftUp(i, e); 59 | size = i + 1; 60 | 61 | return true; 62 | } 63 | 64 | @SuppressWarnings("unchecked") 65 | @Override 66 | public E remove() { 67 | // 删除返回首个元素 68 | // 后续元素前移 69 | 70 | if (size == 0) { 71 | return null; 72 | } 73 | 74 | final Object[] es = queue; 75 | E result = (E) es[0]; // 首个元素 76 | es[0] = null; // 删除首个元素 77 | 78 | int newCapacity = --size; 79 | 80 | // 后续元素前移 81 | Object[] newQueue = new Object[newCapacity]; 82 | System.arraycopy(queue, 1, newQueue, 0, 83 | newCapacity); 84 | 85 | queue = newQueue; 86 | 87 | return result; 88 | } 89 | 90 | private void grow(int minCapacity) { 91 | int oldCapacity = queue.length; 92 | 93 | // 如果是小数组则容量加倍; 94 | // 如果是大数组则容量加50% 95 | int newCapacity = oldCapacity 96 | + ((oldCapacity < 64) ? (oldCapacity + 2) 97 | : (oldCapacity >> 1)); 98 | 99 | queue = Arrays.copyOf(queue, newCapacity); 100 | } 101 | 102 | private void siftUp(int k, E x) { 103 | if (comparator != null) { 104 | siftUpUsingComparator(k, x, queue, comparator); 105 | } else { 106 | siftUpComparable(k, x, queue); 107 | } 108 | } 109 | 110 | @SuppressWarnings("unchecked") 111 | private static void siftUpComparable(int k, T x, 112 | Object[] es) { 113 | 114 | Comparable key = (Comparable) x; 115 | 116 | // 从后往前遍历队列 117 | for (int i = k; i > 0; i--) { 118 | // 与队列的前一位进行比较; 119 | // 如果比前一位小,则进行位置交换,交换完成后,再与前一位比较;否则比较结束。 120 | int preIndex = i - 1; 121 | Object pre = es[preIndex]; 122 | 123 | if (key.compareTo((T) pre) >= 0) { 124 | break; 125 | } 126 | 127 | es[k] = pre; 128 | k = preIndex; 129 | } 130 | 131 | es[k] = key; 132 | } 133 | 134 | @SuppressWarnings("unchecked") 135 | private static void siftUpUsingComparator(int k, 136 | T x, Object[] es, Comparator cmp) { 137 | // 从后往前遍历队列 138 | for (int i = k; i > 0; i--) { 139 | // 与队列的前一位进行比较; 140 | // 如果比前一位小,则进行位置交换,交换完成后,再与前一位比较;否则比较结束。 141 | int preIndex = i - 1; 142 | Object pre = es[preIndex]; 143 | 144 | if (cmp.compare(x, (T) pre) >= 0) { 145 | break; 146 | } 147 | 148 | es[k] = pre; 149 | k = preIndex; 150 | } 151 | 152 | es[k] = x; 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/AvlNode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * AVL Node. 8 | * 9 | * @since 1.0.0 2020年10月28日 10 | * @author Way Lau 11 | */ 12 | public class AvlNode { 13 | private T data; 14 | private AvlNode left; // 左结点 15 | private AvlNode right; // 右结点 16 | private Integer height; // 节点高度 17 | 18 | AvlNode(T data) { 19 | this(data, null, null); 20 | } 21 | 22 | AvlNode(T data, AvlNode left, AvlNode right) { 23 | this.data = data; 24 | this.left = left; 25 | this.right = right; 26 | this.height = 0; 27 | } 28 | 29 | public T getData() { 30 | return data; 31 | } 32 | 33 | public void setData(T data) { 34 | this.data = data; 35 | } 36 | 37 | public AvlNode getLeft() { 38 | return left; 39 | } 40 | 41 | public void setLeft(AvlNode left) { 42 | this.left = left; 43 | } 44 | 45 | public AvlNode getRight() { 46 | return right; 47 | } 48 | 49 | public void setRight(AvlNode right) { 50 | this.right = right; 51 | } 52 | 53 | public Integer getHeight() { 54 | return height; 55 | } 56 | 57 | public void setHeight(Integer height) { 58 | this.height = height; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/BinarySearchTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.List; 7 | /** 8 | * Binary Search Tree. 9 | * 10 | * @since 1.0.0 2020年9月23日 11 | * @author Way Lau 12 | */ 13 | public interface BinarySearchTree { 14 | boolean isEmpty(); // 判断树是否为空 15 | 16 | void insert(E e); // 插入节点 17 | 18 | void remove(E e); // 删除节点 19 | 20 | E findMin(); // 找最小节点 21 | 22 | E findMax(); // 找最大节点 23 | 24 | List preOrder();// 前序遍历 25 | 26 | List infixOrder(); // 中序遍历 27 | 28 | List postOrder(); // 后序遍历 29 | 30 | void print(); // 打印树的信息 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/BinaryTreeNode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * BinaryTree Node. 8 | * 9 | * @since 1.0.0 2020年8月13日 10 | * @author Way Lau 11 | */ 12 | public class BinaryTreeNode { 13 | 14 | private T data; 15 | 16 | private BinaryTreeNode left; // 左结点 17 | 18 | private BinaryTreeNode right; // 右结点 19 | 20 | BinaryTreeNode(T data) { 21 | this(data, null, null); 22 | } 23 | 24 | BinaryTreeNode(T data, BinaryTreeNode left, 25 | BinaryTreeNode right) { 26 | this.left = left; 27 | this.right = right; 28 | this.data = data; 29 | } 30 | 31 | public T getData() { 32 | return data; 33 | } 34 | 35 | public void setData(T data) { 36 | this.data = data; 37 | } 38 | 39 | public BinaryTreeNode getLeft() { 40 | return left; 41 | } 42 | 43 | public void setLeft(BinaryTreeNode left) { 44 | this.left = left; 45 | } 46 | 47 | public BinaryTreeNode getRight() { 48 | return right; 49 | } 50 | 51 | public void setRight(BinaryTreeNode right) { 52 | this.right = right; 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/ConcurrentSkipListMapDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | 7 | import java.util.Map; 8 | import java.util.concurrent.ConcurrentSkipListMap; 9 | 10 | /** 11 | * ConcurrentSkipListMap Demo: Word Count. 12 | * 13 | * @since 1.0.0 2020年6月14日 14 | * @author Way Lau 15 | */ 16 | public class ConcurrentSkipListMapDemo { 17 | 18 | /** 19 | * @param args 20 | */ 21 | @SuppressWarnings("preview") 22 | public static void main(String[] args) { 23 | Map wordCountStore = new ConcurrentSkipListMap<>(); 24 | 25 | // JDK13之后 26 | String wordString = """ 27 | Give me the strength lightly to bear my joys and sorrows 28 | Give me the strength to make my love fruitful in service 29 | Give me the strength never to disown the poor or bend my knees 30 | before insolent might 31 | Give me the strength to raise my mind high above daily trifles 32 | And give me the strength to surrender my strength to thy will with love 33 | """; 34 | 35 | // 转为字符串数组. 36 | // 换行符和头尾空格要特殊处理 37 | String[] words = wordString.replace("\n", " ") 38 | .strip().split(" "); 39 | 40 | for (String word : words) { 41 | 42 | // key统一为小写 43 | String key = word.toLowerCase();// 转为小写 44 | 45 | Integer value = wordCountStore.get(key); 46 | 47 | // 如果value不存在,则先赋值为0 48 | if (value == null) { 49 | value = 0; 50 | } 51 | 52 | // 累加1 53 | value += 1; 54 | 55 | // 存到Map中 56 | wordCountStore.put(key, value); 57 | } 58 | 59 | // 输出结果到控制台 60 | for (Map.Entry entry : wordCountStore 61 | .entrySet()) { 62 | String key = entry.getKey(); 63 | Integer value = entry.getValue(); 64 | System.out.println(key + ": " + value); 65 | } 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/Consumer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.concurrent.BlockingQueue; 7 | 8 | /** 9 | * Consumer 10 | * 11 | * @since 1.0.0 2020年5月29日 12 | * @author Way Lau 13 | */ 14 | 15 | class Consumer implements Runnable { 16 | 17 | private final BlockingQueue queue; 18 | 19 | private final String name; 20 | 21 | Consumer(String name, BlockingQueue queue) { 22 | this.queue = queue; 23 | this.name = name; 24 | } 25 | 26 | public void run() { 27 | try { 28 | while (true) { 29 | // 模拟耗时操作 30 | Thread.sleep(2000L); 31 | consume(queue.take()); 32 | } 33 | } catch (InterruptedException ex) { 34 | ex.printStackTrace(); 35 | } 36 | } 37 | 38 | void consume(Object x) { 39 | System.out.println(this.name + " consume " + x); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/GomokuGame.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Gomoku Gamme. 8 | * 9 | * @since 1.0.0 2020年5月5日 10 | * @author Way Lau 11 | */ 12 | public class GomokuGame { 13 | 14 | /** 15 | * 16 | */ 17 | public GomokuGame() { 18 | // TODO Auto-generated constructor stub 19 | } 20 | 21 | /** 22 | * @param args 23 | */ 24 | public static void main(String[] args) { 25 | // TODO Auto-generated method stub 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/GraphAStar.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.Comparator; 9 | import java.util.HashMap; 10 | import java.util.HashSet; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.Set; 14 | 15 | import com.waylau.java.demo.datastructure.Graph.Edge; 16 | import com.waylau.java.demo.datastructure.Graph.Vertex; 17 | 18 | /** 19 | * In computer science, A* is a computer algorithm that is widely used in path 20 | * finding and graph traversal, the process of plotting an efficiently 21 | * traversable path between multiple points, called nodes. 22 | * 23 | * @since 1.0.0 2020年11月25日 24 | * @author Way Lau 25 | */ 26 | public class GraphAStar> { 27 | public GraphAStar() { 28 | 29 | } 30 | 31 | /** 32 | * 从开始点到结束点使用A*算法查找路径,如果不存在路径,则返回NULL 33 | * 34 | * @param graph Graph to search. 35 | * @param start Start vertex. 36 | * @param goal Goal vertex. 37 | * 38 | * @return 从开始点到结束点边的列表,如果不存在,则返回NULL 39 | */ 40 | public List> aStar(Graph graph, 41 | Graph.Vertex start, Graph.Vertex goal) { 42 | final int size = graph.getVertices().size(); // 用于适当调整数据结构的大小 43 | final Set> closedSet = new HashSet>( 44 | size); // 已评估的节点集。 45 | final List> openSet = new ArrayList>( 46 | size); // 要评估的暂定节点的集合,最初包含起始节点 47 | openSet.add(start); 48 | final Map, Graph.Vertex> cameFrom = new HashMap, Graph.Vertex>( 49 | size); // 导航节点 50 | final Map, Integer> gScore = new HashMap, Integer>(); // 从开始沿最知名的路径的权值 51 | gScore.put(start, 0); 52 | 53 | // 从开始到目标到y的估计总权值 54 | final Map, Integer> fScore = new HashMap, Integer>(); 55 | for (Graph.Vertex v : graph.getVertices()) { 56 | fScore.put(v, Integer.MAX_VALUE); 57 | } 58 | 59 | fScore.put(start, 60 | heuristicCostEstimate(start, goal)); 61 | 62 | final Comparator> comparator = new Comparator>() { 63 | /** 64 | * {@inheritDoc} 65 | */ 66 | @Override 67 | public int compare(Vertex o1, Vertex o2) { 68 | if (fScore.get(o1) < fScore.get(o2)) { 69 | return -1; 70 | } 71 | 72 | if (fScore.get(o2) < fScore.get(o1)) { 73 | return 1; 74 | } 75 | 76 | return 0; 77 | } 78 | }; 79 | 80 | while (!openSet.isEmpty()) { 81 | final Graph.Vertex current = openSet.get(0); 82 | if (current.equals(goal)) { 83 | return reconstructPath(cameFrom, goal); 84 | } 85 | 86 | openSet.remove(0); 87 | closedSet.add(current); 88 | 89 | for (Graph.Edge edge : current.getEdges()) { 90 | final Graph.Vertex neighbor = edge 91 | .getToVertex(); 92 | 93 | if (closedSet.contains(neighbor)) { 94 | continue; // 忽略已评估的 95 | } 96 | 97 | final int tenativeGScore = gScore 98 | .get(current) 99 | + distanceBetween(current, 100 | neighbor); // 路径长度 101 | 102 | if (!openSet.contains(neighbor)) { 103 | openSet.add(neighbor); // 发现新结点 104 | } else if (tenativeGScore >= gScore 105 | .get(neighbor)) { 106 | continue; 107 | } 108 | 109 | // 这条路到现在为止是最好的。记录下来! 110 | cameFrom.put(neighbor, current); 111 | gScore.put(neighbor, tenativeGScore); 112 | final int estimatedFScore = gScore 113 | .get(neighbor) 114 | + heuristicCostEstimate(neighbor, 115 | goal); 116 | 117 | fScore.put(neighbor, estimatedFScore); 118 | 119 | // fScore改变了,需要重新排序 120 | Collections.sort(openSet, comparator); 121 | } 122 | } 123 | 124 | return null; 125 | } 126 | 127 | /** 128 | * 默认距离为边的权值。如果开始和下一个之间没有边,则返回Integer.MAX_VALUE; 129 | */ 130 | protected int distanceBetween(Graph.Vertex start, 131 | Graph.Vertex next) { 132 | 133 | for (Edge e : start.getEdges()) { 134 | if (e.getToVertex().equals(next)) { 135 | return e.getCost(); 136 | } 137 | } 138 | 139 | return Integer.MAX_VALUE; 140 | } 141 | 142 | /** 143 | * 默认每个顶点的权值为1 144 | */ 145 | protected int heuristicCostEstimate( 146 | Graph.Vertex start, Graph.Vertex goal) { 147 | return 1; 148 | } 149 | 150 | private List> reconstructPath( 151 | Map, Graph.Vertex> cameFrom, 152 | Graph.Vertex current) { 153 | 154 | final List> totalPath = new ArrayList>(); 155 | 156 | while (current != null) { 157 | final Graph.Vertex previous = current; 158 | current = cameFrom.get(current); 159 | 160 | if (current != null) { 161 | final Graph.Edge edge = current 162 | .getEdge(previous); 163 | totalPath.add(edge); 164 | } 165 | 166 | } 167 | 168 | Collections.reverse(totalPath); 169 | 170 | return totalPath; 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/GraphBreadthFirstTraversal.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Queue; 9 | import com.waylau.java.demo.datastructure.Graph.Edge; 10 | import com.waylau.java.demo.datastructure.Graph.Vertex; 11 | /** 12 | * Breadth-first search (BFS) for traversing or searching graph data structures. 13 | * 14 | * @author Way Lau 15 | * @since 2020-10-12 16 | */ 17 | public class GraphBreadthFirstTraversal { 18 | @SuppressWarnings("unchecked") 19 | public static final > Graph.Vertex[] breadthFirstTraversal( 20 | Graph graph, 21 | Graph.Vertex source) { 22 | // 用于通过索引查找 23 | final ArrayList> vertices = new ArrayList>(); 24 | vertices.addAll(graph.getVertices()); 25 | 26 | // 用于通过顶点查找 27 | final int n = vertices.size(); 28 | final Map, Integer> vertexToIndex = new HashMap, Integer>(); 29 | 30 | for (int i = 0; i < n; i++) { 31 | final Vertex v = vertices.get(i); 32 | vertexToIndex.put(v, i); 33 | } 34 | 35 | // 邻接矩阵 36 | final byte[][] adj = new byte[n][n]; 37 | 38 | for (int i = 0; i < n; i++) { 39 | final Vertex v = vertices.get(i); 40 | final int idx = vertexToIndex.get(v); 41 | final byte[] array = new byte[n]; 42 | adj[idx] = array; 43 | final List> edges = v.getEdges(); 44 | 45 | for (Edge e : edges) { 46 | array[vertexToIndex 47 | .get(e.getToVertex())] = 1; 48 | } 49 | } 50 | 51 | // visited 用于记录访问过的顶点。初始值都是-1 52 | final byte[] visited = new byte[n]; 53 | 54 | for (int i = 0; i < visited.length; i++) { 55 | visited[i] = -1; 56 | } 57 | 58 | // 返回的结果 59 | final Graph.Vertex[] result = new Graph.Vertex[n]; 60 | 61 | // source为遍历的起点 62 | Vertex element = source; 63 | 64 | int c = 0; 65 | int i = vertexToIndex.get(element); 66 | int k = 0; 67 | 68 | result[k] = element; 69 | visited[i] = 1; 70 | 71 | k++; 72 | 73 | final Queue> queue = new ArrayDeque>(); 74 | queue.add(source); 75 | 76 | while (!queue.isEmpty()) { 77 | element = queue.peek(); 78 | c = vertexToIndex.get(element); 79 | i = 0; 80 | 81 | while (i < n) { 82 | if (adj[c][i] == 1 && visited[i] == -1) { 83 | final Vertex v = vertices.get(i); 84 | queue.add(v); 85 | visited[i] = 1; 86 | result[k] = v; 87 | 88 | k++; 89 | } 90 | 91 | i++; 92 | } 93 | 94 | queue.poll(); 95 | } 96 | 97 | return result; 98 | 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/GraphDepthFirstTraversal.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Stack; 8 | import com.waylau.java.demo.datastructure.Graph.Edge; 9 | import com.waylau.java.demo.datastructure.Graph.Vertex; 10 | /** 11 | * Depth-first search (DFS) for traversing or searching graph data structures. 12 | * 13 | * @author Way Lau 14 | * @since 2020-10-12 15 | */ 16 | public class GraphDepthFirstTraversal { 17 | @SuppressWarnings("unchecked") 18 | public static > Graph.Vertex[] depthFirstTraversal( 19 | Graph graph, 20 | Graph.Vertex source) { 21 | // 用于通过索引查找 22 | final ArrayList> vertices = new ArrayList>(); 23 | 24 | vertices.addAll(graph.getVertices()); 25 | 26 | // 用于通过顶点查找 27 | final int n = vertices.size(); 28 | final Map, Integer> vertexToIndex = new HashMap, Integer>(); 29 | 30 | for (int i = 0; i < n; i++) { 31 | final Vertex v = vertices.get(i); 32 | vertexToIndex.put(v, i); 33 | } 34 | 35 | // 邻接矩阵 36 | final byte[][] adj = new byte[n][n]; 37 | for (int i = 0; i < n; i++) { 38 | final Vertex v = vertices.get(i); 39 | final int idx = vertexToIndex.get(v); 40 | final byte[] array = new byte[n]; 41 | adj[idx] = array; 42 | final List> edges = v.getEdges(); 43 | 44 | for (Edge e : edges) 45 | array[vertexToIndex 46 | .get(e.getToVertex())] = 1; 47 | } 48 | 49 | // visited 用于记录访问过的顶点。初始值都是-1 50 | final byte[] visited = new byte[n]; 51 | 52 | for (int i = 0; i < visited.length; i++) { 53 | visited[i] = -1; 54 | } 55 | 56 | // 返回的结果 57 | final Graph.Vertex[] arr = new Graph.Vertex[n]; 58 | 59 | // source为遍历的起点 60 | Vertex element = source; 61 | 62 | int c = 0; 63 | int i = vertexToIndex.get(element); 64 | int k = 0; 65 | visited[i] = 1; 66 | arr[k] = element; 67 | 68 | k++; 69 | 70 | final Stack> stack = new Stack>(); 71 | stack.push(source); 72 | 73 | while (!stack.isEmpty()) { 74 | element = stack.peek(); 75 | c = vertexToIndex.get(element); 76 | i = 0; 77 | 78 | while (i < n) { 79 | if (adj[c][i] == 1 && visited[i] == -1) { 80 | final Vertex v = vertices.get(i); 81 | stack.push(v); 82 | visited[i] = 1; 83 | element = v; 84 | 85 | c = vertexToIndex.get(element); 86 | i = 0; 87 | 88 | arr[k] = v; 89 | k++; 90 | 91 | continue; 92 | } 93 | 94 | i++; 95 | } 96 | 97 | stack.pop(); 98 | } 99 | 100 | return arr; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/GraphFloydWarshall.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * Floyd–Warshall algorithm is a graph analysis algorithm for finding shortest 12 | * paths in a weighted graph (with positive or negative edge weights). Worst 13 | * case: O(V^3) 14 | * 15 | * @author Way Lau 16 | * @since 2020-11-28 17 | */ 18 | public class GraphFloydWarshall { 19 | 20 | private GraphFloydWarshall() { 21 | 22 | } 23 | 24 | public static Map, Map, Integer>> getAllPairsShortestPaths( 25 | Graph graph) { 26 | 27 | if (graph == null) { 28 | throw (new NullPointerException( 29 | "Graph must be non-NULL.")); 30 | } 31 | 32 | final List> vertices = graph 33 | .getVertices(); 34 | final int[][] sums = new int[vertices 35 | .size()][vertices.size()]; 36 | 37 | for (int i = 0; i < sums.length; i++) { 38 | for (int j = 0; j < sums[i].length; j++) { 39 | sums[i][j] = Integer.MAX_VALUE; 40 | } 41 | } 42 | 43 | final List> edges = graph 44 | .getEdges(); 45 | 46 | for (Graph.Edge e : edges) { 47 | final int indexOfFrom = vertices 48 | .indexOf(e.getFromVertex()); 49 | final int indexOfTo = vertices 50 | .indexOf(e.getToVertex()); 51 | sums[indexOfFrom][indexOfTo] = e.getCost(); 52 | } 53 | 54 | for (int k = 0; k < vertices.size(); k++) { 55 | for (int i = 0; i < vertices.size(); i++) { 56 | for (int j = 0; j < vertices.size(); j++) { 57 | if (i == j) { 58 | sums[i][j] = 0; 59 | } else { 60 | final int ijCost = sums[i][j]; 61 | final int ikCost = sums[i][k]; 62 | final int kjCost = sums[k][j]; 63 | final int summed = (ikCost != Integer.MAX_VALUE 64 | && kjCost != Integer.MAX_VALUE) 65 | ? (ikCost + kjCost) 66 | : Integer.MAX_VALUE; 67 | 68 | if (ijCost > summed) { 69 | sums[i][j] = summed; 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | final Map, Map, Integer>> allShortestPaths = 77 | new HashMap, Map, Integer>>(); 78 | 79 | for (int i = 0; i < sums.length; i++) { 80 | for (int j = 0; j < sums[i].length; j++) { 81 | final Graph.Vertex from = vertices 82 | .get(i); 83 | final Graph.Vertex to = vertices 84 | .get(j); 85 | 86 | Map, Integer> map = allShortestPaths 87 | .get(from); 88 | 89 | if (map == null) { 90 | map = new HashMap, Integer>(); 91 | } 92 | 93 | final int cost = sums[i][j]; 94 | 95 | if (cost != Integer.MAX_VALUE) { 96 | map.put(to, cost); 97 | } 98 | 99 | allShortestPaths.put(from, map); 100 | } 101 | } 102 | 103 | return allShortestPaths; 104 | } 105 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/GraphKruskal.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.PriorityQueue; 8 | 9 | /** 10 | * Kruskal's minimum spanning tree. Only works on undirected graphs. It finds a 11 | * subset of the edges that forms a tree that includes every vertex, where the 12 | * total weight of all the edges in the tree is minimized. 13 | * 14 | * @author Way Lau 15 | * @since 2020-10-12 16 | */ 17 | public class GraphKruskal { 18 | private GraphKruskal() { 19 | } 20 | 21 | public static Graph.CostPathPair getMinimumSpanningTree( 22 | Graph graph) { 23 | if (graph == null) { 24 | throw (new NullPointerException( 25 | "Graph must be non-NULL.")); 26 | } 27 | 28 | // Kruskal的算法只适用于无向图 29 | if (graph.getType() == Graph.TYPE.DIRECTED) 30 | throw (new IllegalArgumentException( 31 | "Undirected graphs only.")); 32 | int cost = 0; 33 | final List> path = new ArrayList>(); 34 | 35 | // 准备数据以存储给定顶点的树的部分 36 | HashMap, HashSet>> membershipMap = 37 | new HashMap, HashSet>>(); 38 | 39 | for (Graph.Vertex v : graph 40 | .getVertices()) { 41 | HashSet> set = new HashSet>(); 42 | set.add(v); 43 | membershipMap.put(v, set); 44 | } 45 | 46 | // 把边排成队列来考虑所有边,从权值最低的边开始 47 | PriorityQueue> edgeQueue = new PriorityQueue>( 48 | graph.getEdges()); 49 | 50 | while (!edgeQueue.isEmpty()) { 51 | Graph.Edge edge = edgeQueue.poll(); 52 | // 如果从顶点和到顶点来自树的不同部分,则将此边添加到结果和并集顶点的部分 53 | if (!isTheSamePart(edge.getFromVertex(), 54 | edge.getToVertex(), membershipMap)) { 55 | union(edge.getFromVertex(), 56 | edge.getToVertex(), membershipMap); 57 | path.add(edge); 58 | cost += edge.getCost(); 59 | } 60 | } 61 | 62 | return (new Graph.CostPathPair(cost, 63 | path)); 64 | } 65 | 66 | private static boolean isTheSamePart( 67 | Graph.Vertex v1, 68 | Graph.Vertex v2, 69 | 70 | HashMap, HashSet>> membershipMap) { 71 | return membershipMap.get(v1) == membershipMap 72 | .get(v2); 73 | } 74 | 75 | private static void union(Graph.Vertex v1, 76 | Graph.Vertex v2, 77 | HashMap, HashSet>> membershipMap) { 78 | HashSet> firstSet = membershipMap 79 | .get(v1); // 第一个 set最大 80 | 81 | HashSet> secondSet = membershipMap 82 | .get(v2); 83 | 84 | // 我们想把较小的集合包含在较大的集合中,所以第二集合不能大于第一集合 85 | if (secondSet.size() > firstSet.size()) { 86 | HashSet> tempSet = firstSet; 87 | firstSet = secondSet; 88 | secondSet = tempSet; 89 | } 90 | 91 | // 从较小的集合改变每个顶点的成员 92 | for (Graph.Vertex v : secondSet) { 93 | membershipMap.put(v, firstSet); 94 | } 95 | 96 | // 把所有顶点从小集加到大集 97 | firstSet.addAll(secondSet); 98 | } 99 | 100 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/GraphPrim.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashSet; 8 | import java.util.List; 9 | import java.util.PriorityQueue; 10 | import java.util.Queue; 11 | import java.util.Set; 12 | 13 | /** 14 | * Prim's minimum spanning tree. Only works on undirected graphs. It finds a 15 | * subset of the edges that forms a tree that includes every vertex, where the 16 | * total weight of all the edges in the tree is minimized. 17 | * 18 | * @author Way Lau 19 | * @since 2020-11-22 20 | */ 21 | public class GraphPrim { 22 | private GraphPrim() { 23 | 24 | } 25 | 26 | public static Graph.CostPathPair getMinimumSpanningTree( 27 | Graph graph, 28 | Graph.Vertex start) { 29 | if (graph == null) { 30 | throw (new NullPointerException( 31 | "Graph must be non-NULL.")); 32 | } 33 | 34 | // Prim算法只适用于无向图 35 | if (graph.getType() == Graph.TYPE.DIRECTED) { 36 | throw (new IllegalArgumentException( 37 | "Undirected graphs only.")); 38 | } 39 | 40 | int cost = 0; 41 | final Set> unvisited = new HashSet>(); 42 | unvisited.addAll(graph.getVertices()); 43 | unvisited.remove(start); // O(1) 44 | 45 | final List> path = new ArrayList>(); 46 | final Queue> edgesAvailable = new PriorityQueue>(); 47 | Graph.Vertex vertex = start; 48 | 49 | while (!unvisited.isEmpty()) { 50 | // 将所有边添加到未访问的顶点 51 | for (Graph.Edge e : vertex 52 | .getEdges()) { 53 | if (unvisited.contains(e.getToVertex())) { 54 | edgesAvailable.add(e); 55 | } 56 | } 57 | 58 | // 删除最低开销边 59 | final Graph.Edge e = edgesAvailable 60 | .remove(); 61 | cost += e.getCost(); 62 | path.add(e); // O(1) 63 | vertex = e.getToVertex(); 64 | unvisited.remove(vertex); // O(1) 65 | } 66 | 67 | return (new Graph.CostPathPair(cost, 68 | path)); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/HashMapDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * HashMap Demo: Word Count. 11 | * 12 | * @since 1.0.0 2020年6月13日 13 | * @author Way Lau 14 | */ 15 | public class HashMapDemo { 16 | 17 | /** 18 | * @param args 19 | */ 20 | @SuppressWarnings("preview") 21 | public static void main(String[] args) { 22 | Map wordCountStore = new HashMap<>(); 23 | 24 | // JDK13之后 25 | String wordString = """ 26 | Give me the strength lightly to bear my joys and sorrows 27 | Give me the strength to make my love fruitful in service 28 | Give me the strength never to disown the poor or bend my knees 29 | before insolent might 30 | Give me the strength to raise my mind high above daily trifles 31 | And give me the strength to surrender my strength to thy will with love 32 | """; 33 | 34 | // 转为字符串数组. 35 | // 换行符和头尾空格要特殊处理 36 | String[] words = wordString.replace("\n", " ") 37 | .strip().split(" "); 38 | 39 | for (String word : words) { 40 | 41 | // key统一为小写 42 | String key = word.toLowerCase();// 转为小写 43 | 44 | Integer value = wordCountStore.get(key); 45 | 46 | // 如果value不存在,则先赋值为0 47 | if (value == null) { 48 | value = 0; 49 | } 50 | 51 | // 累加1 52 | value += 1; 53 | 54 | // 存到Map中 55 | wordCountStore.put(key, value); 56 | } 57 | 58 | // 输出结果到控制台 59 | for (Map.Entry entry : wordCountStore 60 | .entrySet()) { 61 | String key = entry.getKey(); 62 | Integer value = entry.getValue(); 63 | System.out.println(key + ": " + value); 64 | } 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/HeapPriorityQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.Arrays; 7 | import java.util.Comparator; 8 | 9 | /** 10 | * Heap-based Priority Queue. 11 | * 12 | * @since 1.0.0 2020年9月14日 13 | * @author Way Lau 14 | */ 15 | public class HeapPriorityQueue 16 | implements PriorityQueue { 17 | private static final int DEFAULT_INITIAL_CAPACITY = 11; 18 | 19 | private int size; 20 | 21 | private Object[] queue; 22 | 23 | private final Comparator comparator; 24 | 25 | public HeapPriorityQueue() { 26 | this(DEFAULT_INITIAL_CAPACITY, null); 27 | } 28 | 29 | public HeapPriorityQueue(int initialCapacity) { 30 | this(initialCapacity, null); 31 | } 32 | 33 | public HeapPriorityQueue( 34 | Comparator comparator) { 35 | this(DEFAULT_INITIAL_CAPACITY, comparator); 36 | } 37 | 38 | public HeapPriorityQueue(int initialCapacity, 39 | Comparator comparator) { 40 | if (initialCapacity < 1) { 41 | throw new IllegalArgumentException(); 42 | } 43 | 44 | this.queue = new Object[initialCapacity]; 45 | this.comparator = comparator; 46 | } 47 | 48 | @Override 49 | public boolean add(E e) { 50 | int i = size; 51 | 52 | // 判断容量,自动增长 53 | if (i >= queue.length) { 54 | grow(i + 1); 55 | } 56 | 57 | // 从新排序 58 | siftUp(i, e); 59 | size = i + 1; 60 | 61 | return true; 62 | } 63 | 64 | @Override 65 | public E remove() { 66 | // 删除返回首个元素 67 | // 最后的元素补齐到根节点位置 68 | // 剩余元素向下调整堆 69 | 70 | if (size == 0) { 71 | return null; 72 | } 73 | 74 | final Object[] es = queue; 75 | E result = (E) es[0]; // 首个元素 76 | es[0] = null; 77 | 78 | // 最后的元素先作为根节点 79 | int last = --size; 80 | 81 | // 剩余元素向下调整堆 82 | siftDown(0, (E) es[last]); 83 | 84 | return result; 85 | } 86 | 87 | private void grow(int minCapacity) { 88 | int oldCapacity = queue.length; 89 | 90 | // 如果是小数组则容量加倍; 91 | // 如果是大数组则容量加50% 92 | int newCapacity = oldCapacity 93 | + ((oldCapacity < 64) ? (oldCapacity + 2) 94 | : (oldCapacity >> 1)); 95 | 96 | queue = Arrays.copyOf(queue, newCapacity); 97 | } 98 | 99 | private void siftUp(int k, E x) { 100 | if (comparator != null) { 101 | siftUpUsingComparator(k, x, queue, comparator); 102 | } else { 103 | siftUpComparable(k, x, queue); 104 | } 105 | } 106 | 107 | @SuppressWarnings("unchecked") 108 | private static void siftUpComparable(int k, T x, 109 | Object[] es) { 110 | Comparable key = (Comparable) x; 111 | 112 | while (k > 0) { 113 | // 无带符号右移1位,获取父节点索引 114 | int parent = (k - 1) >>> 1; 115 | 116 | // 如果比父节点小,则进行位置交换;否则比较结束。 117 | Object e = es[parent]; 118 | if (key.compareTo((T) e) >= 0) { 119 | break; 120 | } 121 | 122 | es[k] = e; 123 | k = parent; 124 | } 125 | 126 | es[k] = key; 127 | } 128 | 129 | @SuppressWarnings("unchecked") 130 | private static void siftUpUsingComparator(int k, 131 | T x, Object[] es, Comparator cmp) { 132 | 133 | while (k > 0) { 134 | // 无带符号右移1位,获取父节点索引 135 | int parent = (k - 1) >>> 1; 136 | 137 | // 如果比父节点小,则进行位置交换;否则比较结束。 138 | Object e = es[parent]; 139 | 140 | if (cmp.compare(x, (T) e) >= 0) { 141 | break; 142 | } 143 | 144 | es[k] = e; 145 | k = parent; 146 | } 147 | 148 | es[k] = x; 149 | } 150 | 151 | private void siftDown(int k, E x) { 152 | if (comparator != null) { 153 | siftDownUsingComparator(k, x, queue, size, 154 | comparator); 155 | } else { 156 | siftDownComparable(k, x, queue, size); 157 | } 158 | } 159 | 160 | @SuppressWarnings("unchecked") 161 | private static void siftDownComparable(int k, T x, 162 | Object[] es, int n) { 163 | Comparable key = (Comparable) x; 164 | 165 | int half = n >>> 1; // 取n的一半 166 | 167 | while (k < half) { 168 | // 带符号左移1位 169 | int child = (k << 1) + 1; // 假设左子最小 170 | Object c = es[child]; 171 | int right = child + 1; // 取右子结点 172 | 173 | if (right < n && 174 | ((Comparable) c) 175 | .compareTo((T) es[right]) > 0) { 176 | c = es[child = right]; 177 | } 178 | 179 | 180 | if (key.compareTo((T) c) <= 0) { 181 | break; 182 | } 183 | 184 | es[k] = c; 185 | k = child; 186 | } 187 | 188 | es[k] = key; 189 | 190 | } 191 | 192 | @SuppressWarnings("unchecked") 193 | private static void siftDownUsingComparator( 194 | 195 | int k, T x, Object[] es, int n, 196 | Comparator cmp) { 197 | 198 | int half = n >>> 1; // 取n的一半 199 | 200 | while (k < half) { 201 | // 带符号左移1位 202 | int child = (k << 1) + 1;// 假设左子结点最小 203 | Object c = es[child]; 204 | int right = child + 1; // 取右子结点 205 | 206 | if (right < n && cmp.compare((T) c, 207 | (T) es[right]) > 0) { 208 | c = es[child = right]; 209 | } 210 | 211 | if (cmp.compare(x, (T) c) <= 0) { 212 | break; 213 | } 214 | 215 | es[k] = c; 216 | k = child; 217 | } 218 | 219 | es[k] = x; 220 | } 221 | 222 | } 223 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/Hero.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Hero. 8 | * 9 | * @since 1.0.0 2020年9月14日 10 | * @author Way Lau 11 | */ 12 | public class Hero { 13 | private String name; 14 | 15 | private Integer power; // 战力 16 | 17 | public Hero(String name, Integer power) { 18 | this.name = name; 19 | this.power = power; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public Integer getPower() { 31 | return power; 32 | } 33 | 34 | public void setPower(Integer power) { 35 | this.power = power; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "Hero [name=" + name + ", power=" + power 41 | + "]"; 42 | 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | final int prime = 31; 48 | int result = 1; 49 | result = prime * result 50 | + ((name == null) ? 0 : name.hashCode()); 51 | result = prime * result 52 | + ((power == null) ? 0 : power.hashCode()); 53 | return result; 54 | } 55 | 56 | @Override 57 | public boolean equals(Object obj) { 58 | if (this == obj) 59 | return true; 60 | if (obj == null) 61 | return false; 62 | if (getClass() != obj.getClass()) 63 | return false; 64 | Hero other = (Hero) obj; 65 | if (name == null) { 66 | if (other.name != null) 67 | return false; 68 | } else if (!name.equals(other.name)) 69 | return false; 70 | if (power == null) { 71 | if (other.power != null) 72 | return false; 73 | } else if (!power.equals(other.power)) 74 | return false; 75 | return true; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/HuffmanTree.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Queue; 8 | 9 | /** 10 | * Huffman Tree. 11 | * 12 | * @since 1.0.0 2020年9月8日 13 | * @author Way Lau 14 | */ 15 | public class HuffmanTree { 16 | /** 17 | * 创建Huffman树 18 | * @param 19 | * @param HuffmanTreeNodes 20 | * @return 根节点 21 | */ 22 | public static HuffmanTreeNode createTree( 23 | List> HuffmanTreeNodes) { 24 | while (HuffmanTreeNodes.size() > 1) { 25 | Collections.sort(HuffmanTreeNodes); 26 | HuffmanTreeNode left = HuffmanTreeNodes 27 | .get(HuffmanTreeNodes.size() - 1); 28 | HuffmanTreeNode right = HuffmanTreeNodes 29 | .get(HuffmanTreeNodes.size() - 2); 30 | HuffmanTreeNode parent = new HuffmanTreeNode( 31 | null, 32 | left.getWeight() + right.getWeight()); 33 | 34 | parent.setLeft(left); 35 | parent.setRight(right); 36 | 37 | HuffmanTreeNodes.remove(left); 38 | HuffmanTreeNodes.remove(right); 39 | HuffmanTreeNodes.add(parent); 40 | } 41 | 42 | return HuffmanTreeNodes.get(0); 43 | } 44 | 45 | /** 46 | * 广度优先遍历 47 | * 48 | * @param 49 | * @param root 50 | * @return 51 | */ 52 | public static List> breadth( 53 | HuffmanTreeNode root) { 54 | List> list = new ArrayList>(); 55 | Queue> queue = new ArrayDeque>(); 56 | 57 | if (root != null) { 58 | queue.offer(root); 59 | } 60 | 61 | while (!queue.isEmpty()) { 62 | list.add(queue.peek()); 63 | HuffmanTreeNode HuffmanTreeNode = queue 64 | .poll(); 65 | 66 | if (HuffmanTreeNode.getLeft() != null) { 67 | queue.offer(HuffmanTreeNode.getLeft()); 68 | } 69 | 70 | if (HuffmanTreeNode.getRight() != null) { 71 | queue.offer(HuffmanTreeNode.getRight()); 72 | } 73 | } 74 | 75 | return list; 76 | } 77 | 78 | /** 79 | * 对Huffman树中叶子节点进行编码 80 | * 81 | * @param root 82 | */ 83 | public static void encode(HuffmanTreeNode root) { 84 | encode(root, "0", "1", ""); 85 | } 86 | 87 | public static void encode(HuffmanTreeNode node, 88 | String a, String b, String c) { 89 | if (node.getLeft() != null) { 90 | String temp = c + "0"; 91 | encode(node.getLeft(), "0", "1", temp); 92 | } 93 | 94 | if (node.getRight() != null) { 95 | String temp = c + "1"; 96 | encode(node.getRight(), "0", "1", temp); 97 | } 98 | 99 | if (node.getLeft() == null 100 | && node.getRight() == null) { 101 | node.setCode(c); 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/HuffmanTreeNode.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | /** 4 | * Huffman Tree Node. 5 | * 6 | * @since 1.0.0 2020年9月8日 7 | * @author Way Lau 8 | */ 9 | public class HuffmanTreeNode 10 | implements Comparable> { 11 | 12 | private T data; 13 | 14 | private HuffmanTreeNode left; // 左结点 15 | 16 | private HuffmanTreeNode right; // 右结点 17 | 18 | private Double weight; // 权值 19 | 20 | private String code; // 编码 21 | 22 | public HuffmanTreeNode(T data, double weight) { 23 | this.data = data; 24 | this.weight = weight; 25 | } 26 | 27 | public T getData() { 28 | return data; 29 | } 30 | 31 | public void setData(T data) { 32 | this.data = data; 33 | } 34 | 35 | public HuffmanTreeNode getLeft() { 36 | return left; 37 | } 38 | 39 | public void setLeft(HuffmanTreeNode left) { 40 | this.left = left; 41 | } 42 | 43 | public HuffmanTreeNode getRight() { 44 | return right; 45 | } 46 | 47 | public void setRight(HuffmanTreeNode right) { 48 | this.right = right; 49 | } 50 | 51 | public Double getWeight() { 52 | return weight; 53 | } 54 | 55 | public void setWeight(Double weight) { 56 | this.weight = weight; 57 | } 58 | 59 | public String getCode() { 60 | return code; 61 | } 62 | 63 | public void setCode(String code) { 64 | this.code = code; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return "HuffmanTreeNode [data=" + data + ", weight=" 70 | + weight 71 | + ", code=" + code + "]"; 72 | 73 | } 74 | 75 | @Override 76 | public int compareTo(HuffmanTreeNode o) { 77 | if (o.getWeight() > this.getWeight()) { 78 | return 1; 79 | } 80 | 81 | if (o.getWeight() < this.getWeight()) { 82 | return -1; 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/LinkedBinarySearchTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @since 1.0.0 2020年9月23日 11 | * @author Way Lau 12 | */ 13 | public class LinkedBinarySearchTree> 14 | implements BinarySearchTree { 15 | 16 | private BinaryTreeNode root; 17 | 18 | @Override 19 | public boolean isEmpty() { 20 | return root == null; 21 | } 22 | 23 | @Override 24 | public void insert(E e) { 25 | root = insert(e, root); 26 | } 27 | 28 | @Override 29 | public void remove(E e) { 30 | root = remove(e, root); 31 | } 32 | 33 | @Override 34 | public E findMin() { 35 | return findMin(root).getData(); 36 | } 37 | 38 | @Override 39 | public E findMax() { 40 | return findMax(root).getData(); 41 | } 42 | 43 | @Override 44 | public List preOrder() { 45 | List result = new ArrayList(); 46 | if (isEmpty()) { 47 | return result; 48 | } else { 49 | preOrder(root, result); 50 | } 51 | 52 | return result; 53 | } 54 | 55 | @Override 56 | public List infixOrder() { 57 | List result = new ArrayList(); 58 | if (isEmpty()) { 59 | return result; 60 | } else { 61 | infixOrder(root, result); 62 | } 63 | 64 | return result; 65 | } 66 | 67 | @Override 68 | public List postOrder() { 69 | List result = new ArrayList(); 70 | if (isEmpty()) { 71 | return result; 72 | } else { 73 | postOrder(root, result); 74 | } 75 | 76 | return result; 77 | } 78 | 79 | @Override 80 | public void print() { 81 | if (isEmpty()) { 82 | System.out.println("tree is empty"); 83 | return; 84 | } else { 85 | print(root); 86 | } 87 | } 88 | 89 | private BinaryTreeNode insert(E e, 90 | BinaryTreeNode root) { 91 | // 如果root为空,则当前e节点为根节点 92 | if (null == root) { 93 | return new BinaryTreeNode(e); 94 | } 95 | 96 | // e与root进行比较 97 | int compareResult = e.compareTo(root.getData()); 98 | 99 | // 小于当前根节点 将e插入根节点的左边 100 | if (compareResult < 0) { 101 | root.setLeft(insert(e, root.getLeft())); 102 | } else if (compareResult > 0) { 103 | // 大于当前根节点 将e插入根节点的右边 104 | root.setRight(insert(e, root.getRight())); 105 | } 106 | 107 | return root; 108 | } 109 | 110 | private BinaryTreeNode remove(E e, 111 | BinaryTreeNode root) { 112 | if (null == root) { 113 | return root; 114 | } 115 | 116 | // e与root进行比较 117 | int compareResult = e.compareTo(root.getData()); 118 | 119 | // 小于当前根节点 120 | if (compareResult < 0) { 121 | root.setLeft(remove(e, root.getLeft())); 122 | } else if (compareResult > 0) { 123 | // 大于当前根节点 124 | root.setRight(remove(e, root.getRight())); 125 | } else if (root.getLeft() != null 126 | && root.getRight() != null) { 127 | // 找到右边最小的节点 128 | root.setData( 129 | findMin(root.getRight()).getData()); 130 | 131 | // 当前节点的右边等于原节点右边删除已经被选为的替代节点 132 | root.setRight(remove(root.getData(), 133 | root.getRight())); 134 | } else { 135 | root = (root.getLeft() != null) ? root.getLeft() 136 | : root.getRight(); 137 | } 138 | 139 | return root; 140 | } 141 | 142 | private BinaryTreeNode findMin( 143 | BinaryTreeNode root) { 144 | if (null == root) { 145 | return root; 146 | } else if (root.getLeft() == null) { 147 | return root; 148 | } 149 | 150 | // 递归查找 151 | return findMin(root.getLeft()); 152 | } 153 | 154 | private BinaryTreeNode findMax( 155 | BinaryTreeNode root) { 156 | if (null == root) { 157 | return root; 158 | } else if (root.getRight() == null) { 159 | return root; 160 | } 161 | 162 | // 递归查找 163 | return findMax(root.getRight()); 164 | } 165 | 166 | // 前序遍历 167 | private void preOrder(BinaryTreeNode root, 168 | List result) { 169 | if (root == null) { 170 | return; 171 | } 172 | 173 | result.add(root.getData()); 174 | preOrder(root.getLeft(), result); 175 | preOrder(root.getRight(), result); 176 | } 177 | 178 | // 中序遍历 179 | private void infixOrder(BinaryTreeNode root, 180 | List result) { 181 | if (root == null) { 182 | return; 183 | } 184 | 185 | infixOrder(root.getLeft(), result); 186 | result.add(root.getData()); 187 | infixOrder(root.getRight(), result); 188 | } 189 | 190 | // 后序遍历 191 | private void postOrder(BinaryTreeNode root, 192 | List result) { 193 | if (root == null) { 194 | return; 195 | } 196 | 197 | postOrder(root.getLeft(), result); 198 | postOrder(root.getRight(), result); 199 | result.add(root.getData()); 200 | } 201 | 202 | // 打印树的信息 203 | private void print(BinaryTreeNode root) { 204 | if (root != null) { 205 | E leftData = null; 206 | E rightData = null; 207 | 208 | if (null != root.getLeft()) { 209 | leftData = root.getLeft().getData(); 210 | } 211 | 212 | if (null != root.getRight()) { 213 | rightData = root.getRight().getData(); 214 | } 215 | 216 | System.out.printf( 217 | "current: %s, left: %s, right: %s%n", 218 | root.getData(), leftData, rightData); 219 | 220 | print(root.getLeft()); 221 | print(root.getRight()); 222 | } 223 | } 224 | 225 | } 226 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/LinkedBinaryTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Linked BinaryTree. 10 | * 11 | * @since 1.0.0 2020年8月13日 12 | * @author Way Lau 13 | */ 14 | public class LinkedBinaryTree { 15 | // 前序遍历 16 | public void preOrder(BinaryTreeNode root, 17 | List result) { 18 | if (root == null) { 19 | return; 20 | } 21 | 22 | result.add(root.getData()); 23 | 24 | preOrder(root.getLeft(), result); 25 | 26 | preOrder(root.getRight(), result); 27 | } 28 | 29 | // 中序遍历 30 | public void infixOrder(BinaryTreeNode root, 31 | List result) { 32 | if (root == null) { 33 | return; 34 | } 35 | 36 | infixOrder(root.getLeft(), result); 37 | 38 | result.add(root.getData()); 39 | 40 | infixOrder(root.getRight(), result); 41 | } 42 | 43 | // 后序遍历 44 | public void postOrder(BinaryTreeNode root, 45 | List result) { 46 | 47 | if (root == null) { 48 | return; 49 | } 50 | 51 | postOrder(root.getLeft(), result); 52 | 53 | postOrder(root.getRight(), result); 54 | 55 | result.add(root.getData()); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/LinkedBlockingQueueDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.concurrent.BlockingQueue; 7 | import java.util.concurrent.LinkedBlockingQueue; 8 | 9 | /** 10 | * LinkedBlockingQueue Demo 11 | * 12 | * @since 1.0.0 2020年5月23日 13 | * @author Way Lau 14 | */ 15 | class LinkedBlockingQueueDemo { 16 | 17 | public static void main(String[] args) { 18 | 19 | BlockingQueue queue = 20 | new LinkedBlockingQueue(3); 21 | 22 | // 1个生产者 23 | Producer p = new Producer(queue); 24 | 25 | // 2个消费者 26 | Consumer c1 = new Consumer("c1", queue); 27 | Consumer c2 = new Consumer("c2", queue); 28 | 29 | // 启动线程 30 | new Thread(p).start(); 31 | new Thread(c1).start(); 32 | new Thread(c2).start(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/List.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * List 8 | * 9 | * @since 1.0.0 2020年5月7日 10 | * @author Way Lau 11 | */ 12 | public interface List { 13 | // 统计顺序表里数据元素的个数 14 | int size(); 15 | 16 | // 判断顺序表里数据元素是否为空 17 | boolean isEmpty(); 18 | 19 | // 判断是否包含某个数据元素 20 | boolean contains(Object o); 21 | 22 | // 添加数据元素 23 | boolean add(E e); 24 | 25 | // 按照索引获取数据元素 26 | E get(int index); 27 | 28 | // 按照索引设置数据元素 29 | E set(int index, E element); 30 | 31 | // 按照索引移除数据元素 32 | E remove(int index); 33 | 34 | // 添加到表头 35 | void addFirst(E e); 36 | 37 | // 添加到表尾 38 | void addLast(E e); 39 | 40 | // 移除表头 41 | E removeFirst(); 42 | 43 | // 移除表尾 44 | E removeLast(); 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/ListDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Vector; 9 | 10 | /** 11 | * List Demo. 12 | * 13 | * @since 1.0.0 2020年5月3日 14 | * @author Way Lau 15 | */ 16 | public class ListDemo { 17 | 18 | /** 19 | * @param args 20 | */ 21 | public static void main(String[] args) { 22 | List intList = new ArrayList<>(); 23 | 24 | List vectorList = new Vector<>(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/MatrixDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * @since 1.0.0 2020年4月19日 8 | * @author Way Lau 9 | */ 10 | public class MatrixDemo { 11 | 12 | /** 13 | * @param args 14 | */ 15 | public static void main(String[] args) { 16 | int rowNum = 15; // 棋盘行数 17 | int columnNum = 15; // 棋盘列数 18 | 19 | // 初始化五子棋盘面 20 | int[][] gomokuMatrix = new int[rowNum][columnNum]; 21 | gomokuMatrix[6][5] = 1; 22 | gomokuMatrix[6][8] = 2; 23 | gomokuMatrix[7][6] = 1; 24 | gomokuMatrix[7][7] = 2; 25 | gomokuMatrix[8][6] = 2; 26 | gomokuMatrix[8][7] = 1; 27 | gomokuMatrix[8][8] = 1; 28 | gomokuMatrix[9][8] = 2; 29 | 30 | // 打印矩阵 31 | MatrixUtil.printMatrix(gomokuMatrix); 32 | 33 | // 转为COO表示 34 | int[][] cooMatrix = MatrixUtil 35 | .MatrixToCOO(gomokuMatrix); 36 | 37 | // 打印矩阵 38 | MatrixUtil.printMatrix(cooMatrix); 39 | 40 | // COO表示转为稀疏数组 41 | int[][] matrix = MatrixUtil.COOToMatrix(cooMatrix, 42 | rowNum, columnNum); 43 | 44 | // 打印矩阵 45 | MatrixUtil.printMatrix(matrix); 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/MatrixUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Matrix Utility. 8 | * 9 | * @since 1.0.0 2020年5月5日 10 | * @author Way Lau 11 | */ 12 | public class MatrixUtil { 13 | 14 | /** 15 | * 将矩阵转为COO表示 16 | * 17 | * @param matrix 矩阵 18 | * @return COO表示 19 | */ 20 | public static int[][] MatrixToCOO( 21 | int[][] matrix) { 22 | int num = 0; // num为稀疏矩阵非0元素的个数 23 | 24 | for (int row = 0; row < matrix.length; row++) { 25 | for (int column = 0; column < matrix[row].length; column++) { 26 | // 查找非0元素 27 | if (matrix[row][column] != 0) { 28 | num++; 29 | } 30 | } 31 | } 32 | 33 | System.out.println("稀疏矩阵非0元素的个数:" + num); 34 | 35 | // 初始化COO表示的稀疏矩阵 36 | int[][] cooMatrix = new int[3][num]; 37 | 38 | // 给COO表示的稀疏矩阵赋值 39 | int cooNum = 0; // 记录放入COO的非0元素个数 40 | for (int row = 0; row < matrix.length; row++) { 41 | for (int column = 0; column < matrix[row].length; column++) { 42 | 43 | // 查找非0元素 44 | if (matrix[row][column] != 0) { 45 | cooMatrix[0][cooNum] = row; 46 | cooMatrix[1][cooNum] = column; 47 | cooMatrix[2][cooNum] = matrix[row][column]; 48 | 49 | cooNum ++; 50 | } 51 | } 52 | } 53 | 54 | System.out.println("放入COO的非0元素个数:" + cooNum); 55 | 56 | return cooMatrix; 57 | } 58 | 59 | /** 60 | * COO表示转为稀疏矩阵 61 | * 62 | * @param cooMatrix COO表示 63 | * @param rowNum 行数 64 | * @param columnNum 列数 65 | * @return 稀疏矩阵 66 | */ 67 | public static int[][] COOToMatrix(int[][] cooMatrix, 68 | int rowNum, int columnNum) { 69 | int[][] matrix = new int[rowNum][columnNum]; 70 | 71 | // 遍历列 72 | // 因为cooMatrix任意行的列数都是一样的, 73 | // 因此在取列数时,可以取cooMatrix[2].length也可以取cooMatrix[1].length 74 | for (int column = 0; column < cooMatrix[2].length; column++) { 75 | 76 | // 查找非0元素的信息 77 | int matrixRow = cooMatrix[0][column]; 78 | int matrixcolumn = cooMatrix[1][column]; 79 | int matrixValue = cooMatrix[2][column]; 80 | 81 | // 非0元素的信息转为稀疏矩阵中的元素 82 | matrix[matrixRow][matrixcolumn] = matrixValue; 83 | } 84 | 85 | return matrix; 86 | } 87 | 88 | public static void printMatrix(int[][] matrix) { 89 | for (int row = 0; row < matrix.length; row++) { 90 | for (int column = 0; column < matrix[row].length; column++) { 91 | 92 | // 打印元素 93 | System.out.print(matrix[row][column] + " "); 94 | 95 | } 96 | System.out.println(""); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/PriorityQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Priority Queue. 8 | * 9 | * @since 1.0.0 2020年9月14日 10 | * @author Way Lau 11 | */ 12 | public interface PriorityQueue { 13 | /** 14 | * 添加新的对象 15 | * 16 | * @param e 17 | * @return 18 | */ 19 | boolean add(E e); 20 | 21 | /** 22 | * 用于从队列中删除并返回最高优先级对象 23 | * 24 | * @return 25 | */ 26 | E remove(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/Producer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.concurrent.BlockingQueue; 7 | 8 | /** 9 | * Producer 10 | * 11 | * @since 1.0.0 2020年5月29日 12 | * @author Way Lau 13 | */ 14 | class Producer implements Runnable { 15 | 16 | private final BlockingQueue queue; 17 | 18 | Producer(BlockingQueue queue) { 19 | 20 | this.queue = queue; 21 | 22 | } 23 | 24 | public void run() { 25 | try { 26 | while (true) { 27 | // 模拟耗时操作 28 | Thread.sleep(1000L); 29 | queue.put(produce()); 30 | } 31 | } catch (InterruptedException ex) { 32 | ex.printStackTrace(); 33 | } 34 | 35 | } 36 | 37 | String produce() { 38 | String apple = "apple: " 39 | + System.currentTimeMillis(); 40 | System.out.println("produce " + apple); 41 | 42 | return apple; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/QueueDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.Queue; 7 | import java.util.concurrent.ArrayBlockingQueue; 8 | 9 | /** 10 | * @since 1.0.0 2020年4月19日 11 | * @author Way Lau 12 | */ 13 | public class QueueDemo { 14 | 15 | /** 16 | * @param args 17 | */ 18 | public static void main(String[] args) { 19 | // TODO Auto-generated method stub 20 | Queue queue = new ArrayBlockingQueue(10); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/SequentialList.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Sequence List. 8 | * 9 | * @since 1.0.0 2020年5月3日 10 | * @author Way Lau 11 | */ 12 | public class SequentialList implements List { 13 | // 默认容量 14 | private static final int DEFAULT_CAPACITY = 10; 15 | 16 | // 顺序表里面的数据元素 17 | private Object[] elementData; 18 | 19 | // 实际顺序表里面的元素个数 20 | // 不能直接取 elementData.length 21 | private int size; 22 | 23 | // 初始化 24 | public SequentialList(int capacity) { 25 | elementData = new Object[capacity]; 26 | } 27 | 28 | public SequentialList() { 29 | this(DEFAULT_CAPACITY); 30 | } 31 | 32 | @Override 33 | public int size() { 34 | return size; 35 | } 36 | 37 | @Override 38 | public boolean isEmpty() { 39 | return size == 0; 40 | } 41 | 42 | @Override 43 | public boolean contains(Object o) { 44 | // 遍历数组,判断是否存在指定的数据元素 45 | // o可能为null,可能不为null,需分开处理 46 | if (o == null) { 47 | for (int i = 0; i < size; i++) { 48 | if (elementData[i] == null) { 49 | return true; 50 | } 51 | } 52 | } else { 53 | for (int i = 0; i < size; i++) { 54 | if (elementData[i].equals(o)) { 55 | return true; 56 | } 57 | } 58 | } 59 | return false; 60 | } 61 | 62 | @Override 63 | public boolean add(E e) { 64 | // 判断是否越界 65 | if (size == elementData.length) { 66 | throw new IndexOutOfBoundsException("list is full"); 67 | } 68 | 69 | elementData[size] = e; // 添加到数组的最后 70 | size = size + 1; // size累加1位 71 | return true; 72 | } 73 | 74 | 75 | 76 | @Override 77 | public E get(int index) { 78 | // 判断是否越界 79 | if (index < 0 || index > elementData.length - 1) { 80 | throw new IndexOutOfBoundsException("index " + index + " out of bounds"); 81 | } 82 | 83 | return (E) elementData[index]; 84 | } 85 | 86 | @Override 87 | public E set(int index, E element) { 88 | // 判断是否越界 89 | if (index < 0 || index > elementData.length - 1) { 90 | throw new IndexOutOfBoundsException("index " + index + " out of bounds"); 91 | } 92 | 93 | E oldValue = (E)elementData[index]; 94 | elementData[index] = element; 95 | 96 | // 有可能index所对应的位置之前并未设置 97 | if (index > size - 1) { 98 | size = index + 1; 99 | } 100 | 101 | return oldValue; 102 | } 103 | 104 | @Override 105 | public E remove(int index) { 106 | // 判断是否越界 107 | if (index < 0 || index > elementData.length - 1) { 108 | throw new IndexOutOfBoundsException("index " + index + " out of bounds"); 109 | } 110 | 111 | E result = (E) elementData[index]; 112 | 113 | for (int j = index; j < size - 1; j++) { 114 | elementData[j] = elementData[j + 1]; // 数据元素前移 115 | } 116 | 117 | elementData[--size] = null; // 最后的数据置null 118 | 119 | return result; 120 | } 121 | 122 | @Override 123 | public void addFirst(E e) { 124 | // 判断是否已满 125 | if (size == elementData.length) { 126 | throw new IndexOutOfBoundsException("list is full"); 127 | } 128 | 129 | // 判断原数组是否为空. 130 | // 如果为空,则新添加的数据元素直接放到索引为0的位置; 131 | // 如果不为空,则原有数组的数据元素都要往后挪动1个位置, 132 | // 新添加的数据元素放到索引为0的位置 133 | if(!isEmpty()) { 134 | for (int j = size - 1; j >=0; j--) { 135 | elementData[j+1] = elementData[j]; // 数据元素后移 136 | } 137 | } 138 | 139 | elementData[0] = e; 140 | size ++; 141 | } 142 | 143 | @Override 144 | public void addLast(E e) { 145 | add(e); 146 | } 147 | 148 | @Override 149 | public E removeFirst() { 150 | return remove(0); 151 | } 152 | 153 | @Override 154 | public E removeLast() { 155 | return remove(size - 1); 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/SequentialListStack.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * SequentialList Stack 8 | * 9 | * @since 1.0.0 2020年5月7日 10 | * @author Way Lau 11 | */ 12 | public class SequentialListStack implements Stack { 13 | // 栈里面的数据元素 14 | private SequentialList sequentialList; 15 | 16 | public SequentialListStack(int capacity) { 17 | sequentialList = new SequentialList(capacity); 18 | } 19 | 20 | @Override 21 | public int size() { 22 | return sequentialList.size(); 23 | } 24 | 25 | @Override 26 | public boolean isEmpty() { 27 | return sequentialList.isEmpty(); 28 | } 29 | 30 | @Override 31 | public E push(E e) { 32 | // 表尾作为栈顶 33 | sequentialList.addLast(e); 34 | return e; 35 | } 36 | 37 | @Override 38 | public E pop() { 39 | // 表尾作为栈顶 40 | return sequentialList.removeLast(); 41 | } 42 | 43 | @Override 44 | public E peek() { 45 | return sequentialList 46 | .get(sequentialList.size() - 1); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/SinglyLinkedCircularList.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Singly linked circular list. 8 | * 9 | * @since 1.0.0 2020年5月4日 10 | * @author Way Lau 11 | */ 12 | public class SinglyLinkedCircularList 13 | implements List { 14 | // 实际链表里面的元素个数 15 | private int size = 0; 16 | 17 | // 头节点 18 | private Node first; 19 | 20 | // 尾节点 21 | private Node last; 22 | 23 | public SinglyLinkedCircularList() { 24 | } 25 | 26 | @Override 27 | public int size() { 28 | return size; 29 | } 30 | 31 | @Override 32 | public boolean isEmpty() { 33 | return size() == 0; 34 | } 35 | 36 | @Override 37 | public boolean contains(Object o) { 38 | // 遍历数组,判断是否存在指定的数据元素 39 | // o可能为null,可能不为null,需分开处理 40 | if (o == null) { 41 | // 遍历链表 42 | for (Node x = first; x != null; x = x.next) { 43 | if (x.data == null) { 44 | return true; 45 | } 46 | 47 | // 设置退出机制,避免死循环 48 | if (x.next == first) { 49 | break; 50 | } 51 | } 52 | } else { 53 | for (Node x = first; x != null; x = x.next) { 54 | if (o.equals(x.data)) { 55 | return true; 56 | } 57 | 58 | // 设置退出机制,避免死循环 59 | if (x.next == first) { 60 | break; 61 | } 62 | } 63 | } 64 | 65 | return false; 66 | } 67 | 68 | @Override 69 | public boolean add(E e) { 70 | final Node l = last; 71 | 72 | // 构造一个新节点 73 | // 新节点的next指向头结点 74 | final Node newNode = new Node<>(e, first); 75 | last = newNode; 76 | 77 | // 判断尾节点,尾节点为null,则证明链表是空的。 78 | // 如果链表是空的,新增加的节点就作为头结点; 79 | // 如果链表是不空,则原尾节点的next指向新增加的节点 80 | if (l == null) { 81 | first = newNode; 82 | last = newNode; 83 | } else { 84 | l.next = newNode; 85 | } 86 | 87 | size++; // size累加1位 88 | 89 | return true; 90 | } 91 | 92 | @Override 93 | public E get(int index) { 94 | // 判断是否越界 95 | if (index < 0 || index > size - 1) { 96 | throw new IndexOutOfBoundsException( 97 | "index " + index + " out of bounds"); 98 | } 99 | 100 | Node x = first; 101 | 102 | // 遍历链表 103 | for (int i = 0; i < index; i++) { 104 | x = x.next; 105 | } 106 | 107 | return x.data; 108 | } 109 | 110 | @Override 111 | public E set(int index, E element) { 112 | // 判断是否越界 113 | if (index < 0 || index > size - 1) { 114 | throw new IndexOutOfBoundsException( 115 | "index " + index + " out of bounds"); 116 | } 117 | 118 | Node x = first; 119 | 120 | // 遍历链表 121 | for (int i = 0; i < index; i++) { 122 | x = x.next; 123 | } 124 | 125 | E oldVal = x.data; 126 | x.data = element; 127 | 128 | return oldVal; 129 | } 130 | 131 | @Override 132 | public E remove(int index) { 133 | // 判断是否越界 134 | if (index < 0 || index > size - 1) { 135 | throw new IndexOutOfBoundsException( 136 | "index " + index + " out of bounds"); 137 | } 138 | 139 | // x为待删除的节点;p为待删除的前驱节点 140 | Node x, p; 141 | 142 | // index为0则说明待删除的节点是头节点, 143 | // 此时不存在待删除的前驱节点 144 | if (index == 0) { 145 | x = first; // 待删除的节点是头节点 146 | first = first.next; // 新头节点为原头节点的后继节点 147 | } else { 148 | // 从头节点开始遍历链表,查找待删除的前驱节点 149 | // index为待删节点的索引,则index-1为待删节点的前驱节点索引 150 | p = first; 151 | for (int i = 0; i < index - 1; i++) { 152 | p = p.next; 153 | } 154 | 155 | x = p.next; // 找到待删节点 156 | p.next = x.next; // 待删除的前驱节点的next指向待删除节点的后继节点 157 | } 158 | 159 | final E element = x.data; 160 | 161 | x.data = null; // 删除待删节点 162 | size--; // 链表元素个数减1 163 | return element; 164 | } 165 | 166 | private static class Node { 167 | E data; 168 | Node next; 169 | 170 | Node(E element, Node next) { 171 | this.data = element; 172 | this.next = next; 173 | } 174 | } 175 | 176 | @Override 177 | public void addFirst(E e) { 178 | final Node f = first; 179 | 180 | // 构造一个新节点 181 | // 新节点的next指向原头节点 182 | final Node newNode = new Node<>(e, f); 183 | first = newNode; 184 | 185 | // 判断首节点,首节点为null,则证明链表是空的。 186 | // 如果链表是空的,新增加的节点就作为尾结点; 187 | // 如果链表是不空,则尾节点的next指向新增加的节点. 188 | if (f == null) { 189 | last = newNode; 190 | } else { 191 | last.next = newNode; 192 | } 193 | 194 | size++; // size累加1位 195 | } 196 | 197 | @Override 198 | public void addLast(E e) { 199 | add(e); 200 | } 201 | 202 | @Override 203 | public E removeFirst() { 204 | return remove(0); 205 | } 206 | 207 | @Override 208 | public E removeLast() { 209 | return remove(size - 1); 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/SinglyLinkedList.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Singly linked list. 8 | * 9 | * @since 1.0.0 2020年5月4日 10 | * @author Way Lau 11 | */ 12 | public class SinglyLinkedList implements List { 13 | // 实际链表里面的元素个数 14 | private int size = 0; 15 | 16 | // 头节点 17 | private Node first; 18 | 19 | // 尾节点 20 | private Node last; 21 | 22 | public SinglyLinkedList() { 23 | } 24 | 25 | @Override 26 | public int size() { 27 | return size; 28 | } 29 | 30 | @Override 31 | public boolean isEmpty() { 32 | return size() == 0; 33 | } 34 | 35 | @Override 36 | public boolean contains(Object o) { 37 | // 遍历数组,判断是否存在指定的数据元素 38 | // o可能为null,可能不为null,需分开处理 39 | if (o == null) { 40 | for (Node x = first; x != null; x = x.next) { 41 | if (x.data == null) { 42 | return true; 43 | } 44 | } 45 | } else { 46 | for (Node x = first; x != null; x = x.next) { 47 | if (o.equals(x.data)) { 48 | return true; 49 | } 50 | } 51 | } 52 | 53 | return false; 54 | } 55 | 56 | @Override 57 | public boolean add(E e) { 58 | final Node l = last; 59 | 60 | // 构造一个新节点 61 | final Node newNode = new Node<>(e, null); 62 | last = newNode; 63 | 64 | // 判断尾节点,尾节点为null,则证明链表是空的。 65 | // 如果链表是空的,新增加的节点就作为头结点; 66 | // 如果链表是不空,则原尾节点的next指向新增加的节点 67 | if (l == null) { 68 | first = newNode; 69 | last = newNode; 70 | } else { 71 | l.next = newNode; 72 | } 73 | 74 | size++; // size累加1位 75 | 76 | return true; 77 | } 78 | 79 | @Override 80 | public E get(int index) { 81 | // 判断是否越界 82 | if (index < 0 || index > size - 1) { 83 | throw new IndexOutOfBoundsException( 84 | "index " + index + " out of bounds"); 85 | } 86 | 87 | Node x = first; 88 | 89 | // 遍历链表 90 | for (int i = 0; i < index; i++) { 91 | x = x.next; 92 | } 93 | 94 | return x.data; 95 | } 96 | 97 | @Override 98 | public E set(int index, E element) { 99 | // 判断是否越界 100 | if (index < 0 || index > size - 1) { 101 | throw new IndexOutOfBoundsException( 102 | "index " + index + " out of bounds"); 103 | } 104 | 105 | Node x = first; 106 | 107 | // 遍历链表 108 | for (int i = 0; i < index; i++) { 109 | x = x.next; 110 | } 111 | 112 | E oldVal = x.data; 113 | x.data = element; 114 | 115 | return oldVal; 116 | } 117 | 118 | @Override 119 | public E remove(int index) { 120 | // 判断是否越界 121 | if (index < 0 || index > size - 1) { 122 | throw new IndexOutOfBoundsException( 123 | "index " + index + " out of bounds"); 124 | } 125 | 126 | // x为待删除的节点;p为待删除的前驱节点 127 | Node x, p; 128 | 129 | // index为0则说明待删除的节点是头节点, 130 | // 此时不存在待删除的前驱节点 131 | if (index == 0) { 132 | x = first; // 待删除的节点是头节点 133 | first = first.next; // 新头节点为原头节点的后继节点 134 | } else { 135 | // 从头节点开始遍历链表,查找待删除的前驱节点 136 | // index为待删节点的索引,则index-1为待删节点的前驱节点索引 137 | p = first; 138 | for (int i = 0; i < index - 1; i++) { 139 | p = p.next; 140 | } 141 | 142 | x = p.next; // 找到待删节点 143 | p.next = x.next; // 待删除的前驱节点的next指向待删除节点的后继节点 144 | } 145 | 146 | final E element = x.data; 147 | 148 | x.data = null; // 删除待删节点 149 | size--; // 链表元素个数减1 150 | return element; 151 | } 152 | 153 | private static class Node { 154 | E data; 155 | Node next; 156 | 157 | Node(E element, Node next) { 158 | this.data = element; 159 | this.next = next; 160 | } 161 | } 162 | 163 | @Override 164 | public void addFirst(E e) { 165 | final Node f = first; 166 | 167 | // 构造一个新节点 168 | final Node newNode = new Node<>(e, null); 169 | first = newNode; 170 | 171 | // 判断首节点,首节点为null,则证明链表是空的。 172 | // 如果链表是空的,新增加的节点就作为尾结点; 173 | // 如果链表是不空,则新增加的节点的next指向原首节点 174 | if (f == null) { 175 | last = newNode; 176 | } else { 177 | newNode.next = f; 178 | } 179 | 180 | size++; // size累加1位 181 | } 182 | 183 | @Override 184 | public void addLast(E e) { 185 | add(e); 186 | } 187 | 188 | @Override 189 | public E removeFirst() { 190 | return remove(0); 191 | } 192 | 193 | @Override 194 | public E removeLast() { 195 | return remove(size - 1); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/SinglyLinkedListStack.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * SinglyLinkedList Stack 8 | * 9 | * @since 1.0.0 2020年5月7日 10 | * @author Way Lau 11 | */ 12 | public class SinglyLinkedListStack implements Stack { 13 | // 栈里面的数据元素 14 | private SinglyLinkedList singlyLinkedList; 15 | 16 | public SinglyLinkedListStack() { 17 | singlyLinkedList = new SinglyLinkedList(); 18 | } 19 | 20 | @Override 21 | public int size() { 22 | return singlyLinkedList.size(); 23 | } 24 | 25 | @Override 26 | public boolean isEmpty() { 27 | return singlyLinkedList.isEmpty(); 28 | } 29 | 30 | @Override 31 | public E push(E e) { 32 | // 表头作为栈顶 33 | singlyLinkedList.addFirst(e); 34 | return e; 35 | 36 | } 37 | 38 | @Override 39 | public E pop() { 40 | // 表头作为栈顶 41 | return singlyLinkedList.removeFirst(); 42 | } 43 | 44 | @Override 45 | public E peek() { 46 | return singlyLinkedList.get(0); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/Stack.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Stack 8 | * 9 | * @since 1.0.0 2020年5月7日 10 | * @author Way Lau 11 | */ 12 | public interface Stack { 13 | 14 | int size(); // 报告栈的规模 15 | 16 | boolean isEmpty(); // 判断栈是否为空 17 | 18 | E push(E e); // 将元素 e 插至栈顶(入栈) 19 | 20 | E pop(); // 删除栈顶对象,并返回该对象的引用(出栈) 21 | 22 | E peek(); // 引用栈顶对象,但不删除 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/StackDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.Stack; 7 | 8 | /** 9 | * @since 1.0.0 2020年4月19日 10 | * @author Way Lau 11 | */ 12 | public class StackDemo { 13 | 14 | /** 15 | * @param args 16 | */ 17 | public static void main(String[] args) { 18 | // TODO Auto-generated method stub 19 | Stack s = new Stack(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/StreamDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @since 1.0.0 2020年4月19日 11 | * @author Way Lau 12 | */ 13 | public class StreamDemo { 14 | 15 | /** 16 | * @param args 17 | */ 18 | public static void main(String[] args) { 19 | // TODO Auto-generated method stub 20 | 21 | List s = new ArrayList<>(); 22 | s.add("t"); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/datastructure/TextCompressionWithMapDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.Arrays; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * Text compression with Map. 12 | * 13 | * @since 1.0.0 2020年6月15日 14 | * @author Way Lau 15 | */ 16 | public class TextCompressionWithMapDemo { 17 | private static Map dictionary = new HashMap<>(); 18 | 19 | /** 20 | * @param args 21 | */ 22 | public static void main(String[] args) { 23 | // JDK13之后 24 | String wordString = """ 25 | Give me the strength lightly to bear my joys and sorrows 26 | Give me the strength to make my love fruitful in service 27 | Give me the strength never to disown the poor or bend my knees 28 | before insolent might 29 | Give me the strength to raise my mind high above daily trifles 30 | And give me the strength to surrender my strength to thy will with love 31 | """; 32 | 33 | // 转为字符串数组. 34 | // 换行符和头尾空格要特殊处理 35 | String[] words = wordString.replace("\n", " ") 36 | .strip().split(" "); 37 | 38 | makeDictionary(words); 39 | 40 | int[] compressResult = compress(words); 41 | 42 | System.out.println( 43 | "压缩结果:" + Arrays.toString(compressResult)); 44 | 45 | String[] decompressResult = decompress( 46 | compressResult); 47 | 48 | System.out.println("解压结果:" 49 | + Arrays.toString(decompressResult)); 50 | 51 | // 去除多余的符号 52 | System.out.println( 53 | "解压结果:" + Arrays.toString(decompressResult) 54 | .replace("]", "").replace("[", "") 55 | .replace(",", "")); 56 | } 57 | 58 | private static void makeDictionary(String[] words) { 59 | int code = 0; 60 | for (String word : words) { 61 | String key = word; 62 | Integer value = dictionary.get(key); 63 | 64 | // 如果value不存在,就赋一个编码 65 | if (value == null) { 66 | value = code; 67 | code++; 68 | 69 | // 存到Map中 70 | dictionary.put(key, value); 71 | } 72 | } 73 | } 74 | 75 | private static int[] compress(String[] words) { 76 | int len = words.length; 77 | int[] codes = new int[len]; 78 | 79 | for (int i = 0; i < len; i++) { 80 | String key = words[i]; 81 | 82 | // 从字典中取对应的编码 83 | int code = dictionary.get(key); 84 | codes[i] = code; 85 | } 86 | 87 | return codes; 88 | } 89 | 90 | private static String[] decompress(int[] codes) { 91 | int len = codes.length; 92 | String[] words = new String[len]; 93 | 94 | for (int i = 0; i < len; i++) { 95 | int value = codes[i]; 96 | 97 | // 从字典中取对应的键 98 | for (String key : dictionary.keySet()) { 99 | if (dictionary.get(key) == value) { 100 | words[i] = key; 101 | } 102 | } 103 | 104 | } 105 | 106 | return words; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/hannotta/App.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.hannotta; 5 | 6 | /** 7 | * App 8 | * 9 | * @author Way Lau 10 | * @since 2020-11-11 11 | */ 12 | public class App { 13 | public static void main(String[] args) { 14 | new HannottaWindow(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/hannotta/Disc.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.hannotta; 5 | 6 | import java.awt.Color; 7 | import javax.swing.JButton; 8 | 9 | /** 10 | * Disc 11 | * 12 | * @author Way Lau 13 | * @since 2020-11-16 14 | */ 15 | public class Disc extends JButton { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | private int number; 20 | 21 | private TowerPoint point; 22 | 23 | Disc() { 24 | setBackground(Color.YELLOW); 25 | } 26 | 27 | public int getNumber() { 28 | return number; 29 | } 30 | 31 | public void setNumber(int number) { 32 | this.number = number; 33 | } 34 | 35 | public TowerPoint getPoint() { 36 | return point; 37 | } 38 | 39 | public void setPoint(TowerPoint point) { 40 | this.point = point; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/hannotta/Hannotta.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.hannotta; 5 | 6 | /** 7 | * Hannotta 8 | * 9 | * @author Way Lau 10 | * @since 2020-11-30 11 | */ 12 | public class Hannotta { 13 | 14 | private int amountOfDisc = 3; 15 | 16 | private char[] towerNames; 17 | 18 | private int count = 0; 19 | 20 | /** 21 | * 构造函数 22 | */ 23 | public Hannotta(int amountOfDisc, char[] towerNames) { 24 | this.amountOfDisc = amountOfDisc; 25 | this.towerNames = towerNames; 26 | } 27 | 28 | public int solve() { 29 | solve(amountOfDisc, towerNames[0], towerNames[1], 30 | towerNames[2]); 31 | return count; 32 | } 33 | 34 | private void solve(int num, char a, char b, char c) { 35 | count++; 36 | 37 | if (num == 1) { 38 | System.out.println( 39 | "第1个盘从 " + a + " -> " + c + ""); // 如果只剩下一个盘,直接从A移动到C 40 | } else { 41 | solve(num - 1, a, c, b); // 把最上面的所有盘从 A 移动到 B,中间会用到C 42 | System.out.println("第" + num + "个盘从 " + a 43 | + " -> " + c + ""); 44 | solve(num - 1, b, a, c); // 把最B塔上面的所有盘从 B移动到C,中间会用到A 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/hannotta/HannottaWindow.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.hannotta; 5 | 6 | import java.awt.BorderLayout; 7 | import java.awt.event.ActionEvent; 8 | import java.awt.event.ActionListener; 9 | import javax.swing.JFrame; 10 | import javax.swing.JMenu; 11 | import javax.swing.JMenuBar; 12 | import javax.swing.JMenuItem; 13 | 14 | /** 15 | * Hannotta Window. 16 | * 17 | * @author Way Lau 18 | * @since 2020-11-16 19 | */ 20 | public class HannottaWindow extends JFrame 21 | implements ActionListener { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private static final int MAX_DISCS = 10; // 最大碟子數量 26 | 27 | private static final char[] towerNames = { 'A', 'B', 28 | 'C' }; // 塔名 29 | 30 | private final Tower tower; 31 | 32 | private int amountOfDisc = 3; // 碟子数量 33 | 34 | public HannottaWindow() { 35 | 36 | tower = new Tower(towerNames); 37 | 38 | tower.setAmountOfDisc(amountOfDisc); 39 | 40 | tower.setMaxDiscWidth(120); 41 | 42 | tower.setMinDiscWidth(50); 43 | 44 | tower.setDiscHeight(16); 45 | 46 | tower.putDiscOnTower(); 47 | 48 | add(tower, BorderLayout.CENTER); 49 | 50 | JMenuBar menuBar = new JMenuBar(); 51 | 52 | JMenu amountOfDiscMenu = new JMenu("碟子数"); 53 | 54 | for (int i = 1; i <= MAX_DISCS; i++) { 55 | JMenuItem gradeItem = new JMenuItem(i + "", 56 | MenuTypeEnum.DISC.getValue()); 57 | 58 | gradeItem.addActionListener(this); 59 | 60 | amountOfDiscMenu.add(gradeItem); 61 | } 62 | 63 | JMenu settingMenu = new JMenu("设置"); 64 | 65 | JMenuItem renewMenuItem = new JMenuItem("重新开始", 66 | MenuTypeEnum.RENEW.getValue()); 67 | 68 | renewMenuItem.addActionListener(this); 69 | 70 | settingMenu.add(renewMenuItem); 71 | 72 | JMenuItem autoMenuItem = new JMenuItem("自动演示", 73 | MenuTypeEnum.AUTO.getValue()); 74 | 75 | autoMenuItem.addActionListener(this); 76 | 77 | settingMenu.add(autoMenuItem); 78 | 79 | menuBar.add(amountOfDiscMenu); 80 | 81 | menuBar.add(settingMenu); 82 | 83 | setTitle("Hannotta"); 84 | 85 | setJMenuBar(menuBar); 86 | 87 | setResizable(false); 88 | 89 | setVisible(true); 90 | 91 | setBounds(60, 60, 460, 410); 92 | 93 | validate(); 94 | 95 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 96 | 97 | } 98 | 99 | /** 100 | * 事件处理 101 | */ 102 | @Override 103 | public void actionPerformed(ActionEvent e) { 104 | if (e.getSource() instanceof JMenuItem) { 105 | // 碟子数 106 | JMenuItem menuItem = (JMenuItem) e.getSource(); 107 | 108 | int menuTypeValue = menuItem.getMnemonic(); 109 | 110 | if (MenuTypeEnum.DISC 111 | .getValue() == menuTypeValue) { // 碟子数 112 | String menuItemName = menuItem.getText(); 113 | amountOfDisc = Integer 114 | .valueOf(menuItemName); 115 | 116 | tower.setAmountOfDisc(amountOfDisc); 117 | tower.putDiscOnTower(); 118 | } else if (MenuTypeEnum.RENEW 119 | .getValue() == menuTypeValue) {// 重新开始 120 | 121 | tower.setAmountOfDisc(amountOfDisc); 122 | tower.putDiscOnTower(); 123 | } else if (MenuTypeEnum.AUTO 124 | .getValue() == menuTypeValue) { // 自动演示 125 | 126 | tower.setAmountOfDisc(amountOfDisc); 127 | tower.putDiscOnTower(); 128 | 129 | int x = this.getBounds().x 130 | + this.getBounds().width; 131 | int y = this.getBounds().y; 132 | 133 | tower.getAutoMoveDisc().setLocation(x, y); 134 | tower.getAutoMoveDisc().setSize(280, 135 | this.getBounds().height); 136 | tower.getAutoMoveDisc().setVisible(true); 137 | } 138 | 139 | validate(); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/hannotta/MenuTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.hannotta; 2 | 3 | 4 | /** 5 | * Menu item type. 6 | * 7 | * @author Way Lau 8 | * @since 2020-11-16 9 | */ 10 | public enum MenuTypeEnum { 11 | 12 | /** 13 | * 碟子数 14 | */ 15 | DISC(0), 16 | 17 | /** 18 | * 从新开始 19 | */ 20 | RENEW(1), 21 | 22 | /** 23 | * 自动演示 24 | */ 25 | AUTO(2); 26 | 27 | private int value; 28 | 29 | MenuTypeEnum(int value) { 30 | this.value = value; 31 | } 32 | 33 | public int getValue() { 34 | return value; 35 | } 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/hannotta/TowerPoint.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.hannotta; 5 | 6 | import java.awt.Component; 7 | import java.awt.Container; 8 | 9 | /** 10 | * Tower Point. 11 | * 12 | * @author Way Lau 13 | * @since 2020-11-16 14 | */ 15 | public class TowerPoint { 16 | 17 | private int x, y; 18 | 19 | private boolean haveDisc; 20 | 21 | private Disc disc = null; 22 | 23 | public boolean equals(TowerPoint p) { 24 | if (p.getX() == this.x && p.getY() == this.getY()) { 25 | return true; 26 | } else { 27 | return false; 28 | } 29 | } 30 | 31 | public void putDisc(Component com, Container con) { 32 | disc = (Disc) com; 33 | 34 | con.setLayout(null); 35 | con.add(disc); 36 | 37 | int w = disc.getBounds().width; 38 | int h = disc.getBounds().height; 39 | 40 | disc.setBounds(x - w / 2, y - h / 2, w, h); 41 | haveDisc = true; 42 | disc.setPoint(this); 43 | 44 | con.validate(); 45 | } 46 | 47 | public Disc getDiscOnPoint() { 48 | return disc; 49 | } 50 | 51 | public void removeDisc(Component com, Container con) { 52 | if (com != null) { 53 | con.remove(com); 54 | } 55 | 56 | con.validate(); 57 | } 58 | 59 | public TowerPoint(int x, int y) { 60 | super(); 61 | this.x = x; 62 | this.y = y; 63 | } 64 | 65 | public int getX() { 66 | return x; 67 | } 68 | 69 | public void setX(int x) { 70 | this.x = x; 71 | } 72 | 73 | public int getY() { 74 | return y; 75 | } 76 | 77 | public void setY(int y) { 78 | this.y = y; 79 | } 80 | 81 | public boolean isHaveDisc() { 82 | return haveDisc; 83 | } 84 | 85 | public void setHaveDisc(boolean haveDisc) { 86 | this.haveDisc = haveDisc; 87 | } 88 | 89 | public void setDisc(Disc disc) { 90 | this.disc = disc; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/studentinfo/Student.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.studentinfo; 5 | 6 | /** 7 | * Student. 8 | * 9 | * @since 1.0.0 2020年5月1日 10 | * @author Way Lau 11 | */ 12 | public class Student { 13 | private Integer age; // 年龄 14 | private String name; // 姓名 15 | private String phoneNumer; // 电话号码 16 | private String address; // 地址 17 | 18 | public Student(Integer age, String name, String phoneNumer, String address) { 19 | super(); 20 | this.age = age; 21 | this.name = name; 22 | this.phoneNumer = phoneNumer; 23 | this.address = address; 24 | } 25 | 26 | public Integer getAge() { 27 | return age; 28 | } 29 | 30 | public void setAge(Integer age) { 31 | this.age = age; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public void setName(String name) { 39 | this.name = name; 40 | } 41 | 42 | public String getPhoneNumer() { 43 | return phoneNumer; 44 | } 45 | 46 | public void setPhoneNumer(String phoneNumer) { 47 | this.phoneNumer = phoneNumer; 48 | } 49 | 50 | public String getAddress() { 51 | return address; 52 | } 53 | 54 | public void setAddress(String address) { 55 | this.address = address; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/studentinfo/StudentInfoManageSystem.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.studentinfo; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @since 1.0.0 2020年5月1日 11 | * @author Way Lau 12 | */ 13 | public class StudentInfoManageSystem { 14 | 15 | private List studentList = new ArrayList<>(); 16 | 17 | public void addStudent(Student student) { 18 | // 如果已经添加了过该用户的信息,则提示用户。 19 | // 否则将用户信息添加到系统中,并给出提示。 20 | if (studentList.contains(student)) { 21 | System.out.println("Student exsit"); 22 | } else { 23 | studentList.add(student); 24 | System.out.println("Add student success"); 25 | } 26 | } 27 | 28 | public void removeStudent(Student student) { 29 | // 如果用户信息不存在于系统中,则提示用户。 30 | // 否则将用户信息从系统中删除,并给出提示。 31 | if (studentList.contains(student)) { 32 | studentList.remove(student); 33 | System.out.println("Remove student success"); 34 | } else { 35 | System.out.println("Student not exsit"); 36 | } 37 | } 38 | 39 | public List getStudentList() { 40 | // 如果系统中不存在用户,则提示用户。 41 | // 否则将用户信息查询出来返回,并将用户信息打印出来。 42 | if (studentList.isEmpty()) { 43 | System.out.println("No student exsit"); 44 | } else { 45 | for (Student s : studentList) { 46 | System.out.format("Student info: name %s, age %d, phone %s, address %s%n", 47 | s.getName(), s.getAge(), s.getPhoneNumer(), s.getAddress()); 48 | } 49 | } 50 | 51 | return studentList; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/waylau/java/demo/studentinfo/StudentInfoManageSystemDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.studentinfo; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * StudentInfoManageSystem Demo. 10 | * 11 | * @since 1.0.0 2020年5月1日 12 | * @author Way Lau 13 | */ 14 | public class StudentInfoManageSystemDemo { 15 | 16 | /** 17 | * @param args 18 | */ 19 | @SuppressWarnings("unused") 20 | public static void main(String[] args) { 21 | // 初始化系统 22 | StudentInfoManageSystem system = new StudentInfoManageSystem(); 23 | 24 | // 初始化学生信息 25 | Student student = new Student(32, "Way Lau", "17088888888", "Shenzhen"); 26 | 27 | // 添加学生 28 | system.addStudent(student); // Add student success 29 | 30 | // 再次添加学生 31 | system.addStudent(student); // Student exsit 32 | 33 | // 第一次查询所有学生 34 | List studentList = system.getStudentList(); 35 | 36 | // 删除学生 37 | system.removeStudent(student); // Remove student success 38 | 39 | // 再次删除学生 40 | system.removeStudent(student); // Student not exsit 41 | 42 | // 查询所有学生 43 | studentList = system.getStudentList(); // No student exsit 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/resources/att48.tsp: -------------------------------------------------------------------------------- 1 | 1 6734 1453 2 | 2 2233 10 3 | 3 5530 1424 4 | 4 401 841 5 | 5 3082 1644 6 | 6 7608 4458 7 | 7 7573 3716 8 | 8 7265 1268 9 | 9 6898 1885 10 | 10 1112 2049 11 | 11 5468 2606 12 | 12 5989 2873 13 | 13 4706 2674 14 | 14 4612 2035 15 | 15 6347 2683 16 | 16 6107 669 17 | 17 7611 5184 18 | 18 7462 3590 19 | 19 7732 4723 20 | 20 5900 3561 21 | 21 4483 3369 22 | 22 6101 1110 23 | 23 5199 2182 24 | 24 1633 2809 25 | 25 4307 2322 26 | 26 675 1006 27 | 27 7555 4819 28 | 28 7541 3981 29 | 29 3177 756 30 | 30 7352 4506 31 | 31 7545 2801 32 | 32 3245 3305 33 | 33 6426 3173 34 | 34 4608 1198 35 | 35 23 2216 36 | 36 7248 3779 37 | 37 7762 4595 38 | 38 7392 2244 39 | 39 3484 2829 40 | 40 6271 2135 41 | 41 4985 140 42 | 42 1916 1569 43 | 43 7280 4899 44 | 44 7509 3239 45 | 45 10 2676 46 | 46 6807 2993 47 | 47 5185 3258 48 | 48 3023 1942 49 | EOF 50 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/HelloWorldTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo; 5 | 6 | import org.junit.jupiter.api.Test; 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | /** 10 | * HelloWorld Test. 11 | * 12 | * @since 1.0.0 2020年4月12日 13 | * @author Way Lau 14 | */ 15 | class HelloWorldTests { 16 | 17 | @Test 18 | void testGetWords() { 19 | var words = "Hello World"; 20 | var hello = new HelloWorld(words); 21 | 22 | assertEquals(words, hello.getWords()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/AntColonyOptimizationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import java.io.IOException; 7 | import org.junit.jupiter.api.MethodOrderer; 8 | import org.junit.jupiter.api.Order; 9 | import org.junit.jupiter.api.Test; 10 | import org.junit.jupiter.api.TestMethodOrder; 11 | 12 | /** 13 | * AntColonyOptimization Test. 14 | * 15 | * @author Way Lau 16 | * @since 2020-11-06 17 | */ 18 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 19 | public class AntColonyOptimizationTest { 20 | @Order(1) 21 | @Test 22 | public void testAntColonyOptimization() 23 | throws IOException { 24 | AntColonyOptimization AntColonyOptimization = new AntColonyOptimization( 25 | 48, 10, 100, 1.f, 5.f, 0.5f); 26 | 27 | AntColonyOptimization.initDataFromFile("att48.tsp"); 28 | 29 | AntColonyOptimization.solve(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/BinarySearchTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | import org.junit.jupiter.api.MethodOrderer; 8 | import org.junit.jupiter.api.Order; 9 | import org.junit.jupiter.api.Test; 10 | import org.junit.jupiter.api.TestMethodOrder; 11 | 12 | /** 13 | * BinarySearch Tests. 14 | * 15 | * @since 1.0.0 2020年11月27日 16 | * @author Way Lau 17 | */ 18 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 19 | public class BinarySearchTests { 20 | private static final int SIZE = 9999; 21 | 22 | private static Integer[] sortedArray = new Integer[SIZE]; 23 | 24 | // 构造测试用的数组[0,1,2,...,9998] 25 | static { 26 | for (int i = 0; i < SIZE; i++) { 27 | sortedArray[i] = i; 28 | } 29 | } 30 | 31 | // 待查找的值的索引 32 | private static int searchedValueIndex = SIZE 33 | - (SIZE / 4); 34 | 35 | // 待查找的值在数组中 36 | private static Integer searchedValueInArray = sortedArray[searchedValueIndex]; 37 | 38 | // 待查找的值不在数组中 39 | private static Integer searchedValueNotInArray = 111111; 40 | 41 | @Order(1) 42 | @Test 43 | public void testBinarySearch() { 44 | // 测试查找的数据在数组内 45 | int index = BinarySearch.find(searchedValueInArray, 46 | sortedArray); 47 | 48 | assertTrue(index == searchedValueIndex); 49 | 50 | // 测试查找的数据不在数组内 51 | index = BinarySearch.find(searchedValueNotInArray, 52 | sortedArray); 53 | 54 | assertTrue(index == Integer.MAX_VALUE); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/FibonacciSequenceBasicTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import org.junit.jupiter.api.MethodOrderer; 7 | import org.junit.jupiter.api.Order; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.TestMethodOrder; 10 | 11 | /** 12 | * FibonacciSequenceBasic Test. 13 | * 14 | * @author Way Lau 15 | * @since 2020-11-27 16 | */ 17 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 18 | public class FibonacciSequenceBasicTests { 19 | @Order(1) 20 | @Test 21 | public void testFibonacciTiming() { 22 | int num = 45; 23 | long start = System.currentTimeMillis(); 24 | int result = FibonacciSequenceBasic.fibonacci(num); 25 | long cost = System.currentTimeMillis() - start; 26 | System.out.println("num:" + num + "; result=" 27 | + result + "; cost:" + cost); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/FibonacciSequenceForwarCalculationTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | import org.junit.jupiter.api.MethodOrderer; 9 | import org.junit.jupiter.api.Order; 10 | import org.junit.jupiter.api.Test; 11 | import org.junit.jupiter.api.TestMethodOrder; 12 | 13 | /** 14 | * FibonacciSequenceForwarCalculation Tests. 15 | * 16 | * @author Way Lau 17 | * @since 2020-11-27 18 | */ 19 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 20 | public class FibonacciSequenceForwarCalculationTests { 21 | @Order(1) 22 | @Test 23 | public void testFibonacci() { 24 | int result = FibonacciSequenceForwardCalculation.fibonacci(1); 25 | assertTrue(result == 1); 26 | 27 | int result2 = FibonacciSequenceForwardCalculation.fibonacci(2); 28 | assertTrue(result2 == 1); 29 | 30 | int result3 = FibonacciSequenceForwardCalculation.fibonacci(3); 31 | assertTrue(result3 == 2); 32 | } 33 | 34 | @Order(2) 35 | @Test 36 | public void testFibonacciTiming() { 37 | int num = 45; 38 | long start = System.currentTimeMillis(); 39 | int result = FibonacciSequenceForwardCalculation.fibonacci(num); 40 | long cost = System.currentTimeMillis() - start; 41 | 42 | System.out.println("num:" + num + "; result=" + result + "; cost:" + cost); 43 | } 44 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/FibonacciSequenceWithCacheTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import org.junit.jupiter.api.MethodOrderer; 7 | import org.junit.jupiter.api.Order; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.TestMethodOrder; 10 | 11 | /** 12 | * FibonacciSequenceWithCache Test. 13 | * 14 | * @author Way Lau 15 | * @since 2020-11-27 16 | */ 17 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 18 | public class FibonacciSequenceWithCacheTests { 19 | @Order(1) 20 | @Test 21 | public void testFibonacciTiming() { 22 | int num = 45; 23 | long start = System.currentTimeMillis(); 24 | int result = FibonacciSequenceWithCache 25 | .fibonacci(num); 26 | long cost = System.currentTimeMillis() - start; 27 | 28 | System.out.println("num:" + num + "; result=" 29 | + result + "; cost:" + cost); 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/GeneticAlgorithmMaxValueTest.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.algorithm; 2 | 3 | import org.junit.jupiter.api.MethodOrderer; 4 | import org.junit.jupiter.api.Order; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.TestMethodOrder; 7 | 8 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 9 | public class GeneticAlgorithmMaxValueTest { 10 | 11 | @Order(1) 12 | @Test 13 | public void testGeneticAlgorithm() { 14 | int num = 24; 15 | 16 | // 创建遗传算法驱动对象 17 | GeneticAlgorithmMaxValue ga = new GeneticAlgorithmMaxValue( 18 | num); 19 | 20 | ga.caculte(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/GraphColoringProblemTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | /** 7 | * GraphColoringProblem Tests. 8 | * 9 | * @author Way Lau 10 | * @since 2020-11-30 11 | */ 12 | public class GraphColoringProblemTests { 13 | 14 | public static void main(String[] args) { 15 | int n = 5; // 节点数 16 | int m = 3; // 限制图多少种颜色 17 | 18 | // 初始化图.结点之间的关系,0表示不相邻,1表示相邻 19 | int[][] graph = { { 0, 1, 1, 0, 0 }, 20 | { 1, 0, 1, 1, 1 }, { 1, 1, 0, 0, 1 }, 21 | { 0, 1, 0, 0, 1 }, { 0, 1, 1, 1, 0 } }; 22 | 23 | int[] result = GraphColoringProblem 24 | .graphColor(graph, n, m);// 获取图着色结果 25 | 26 | // 输出结果 27 | if (result == null) 28 | System.out.println( 29 | m + " 种颜色无法给 " + n + "个结点的图上色"); 30 | else { 31 | for (int i = 0; i < n; i++) { 32 | System.out.print(result[i] + " "); 33 | } 34 | 35 | System.out.println(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/GreedyAlgorithmTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | import org.junit.jupiter.api.Order; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * GreedyAlgorithm Tests 13 | * 14 | * @since 1.0.0 2020年11月28日 15 | * @author Way Lau 16 | */ 17 | public class GreedyAlgorithmTests { 18 | 19 | @Order(1) 20 | @Test 21 | public void testGreedyAlgorithm() { 22 | int[] array = {1, 3, 2}; 23 | 24 | int result = GreedyAlgorithm.maxNumber(array); 25 | assertTrue(result == 1); 26 | 27 | int[] array2 = {10, 6, 9, 3, 7, 4, 1, 3, 2, 0, 11, 7}; 28 | 29 | result = GreedyAlgorithm.maxNumber(array2); 30 | assertTrue(result == 3); 31 | } 32 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/MergeSortTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | import java.util.Random; 8 | import org.junit.jupiter.api.MethodOrderer; 9 | import org.junit.jupiter.api.Order; 10 | import org.junit.jupiter.api.Test; 11 | import org.junit.jupiter.api.TestMethodOrder; 12 | 13 | /** 14 | * MergeSort Test. 15 | * 16 | * @since 1.0.0 2020年11月27日 17 | * @author Way Lau 18 | */ 19 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 20 | public class MergeSortTests { 21 | 22 | private static final Random RANDOM = new Random(); 23 | 24 | private static final int SIZE = 10000; 25 | 26 | private static Integer[] unsorted = null; // 未排序 27 | 28 | private static Integer[] sorted = null; // 已排序 29 | 30 | private static Integer[] reverse = null; // 反转 31 | 32 | static { 33 | unsorted = new Integer[SIZE]; 34 | int i = 0; 35 | 36 | while (i < unsorted.length) { 37 | int j = RANDOM.nextInt(unsorted.length * 10); 38 | unsorted[i++] = j; 39 | } 40 | 41 | sorted = new Integer[SIZE]; 42 | 43 | for (i = 0; i < sorted.length; i++) { 44 | sorted[i] = i; 45 | } 46 | 47 | reverse = new Integer[SIZE]; 48 | 49 | for (i = (reverse.length - 1); i >= 0; i--) { 50 | reverse[i] = (SIZE - 1) - i; 51 | } 52 | } 53 | 54 | @Order(1) 55 | @Test 56 | public void testMergeSortsInPlace() { 57 | // Merge sort 58 | 59 | Integer[] result = MergeSort.sort( 60 | MergeSort.SPACE_TYPE.IN_PLACE, 61 | unsorted.clone()); 62 | assertTrue(check(result)); 63 | 64 | result = MergeSort.sort( 65 | MergeSort.SPACE_TYPE.IN_PLACE, 66 | sorted.clone()); 67 | assertTrue(check(result)); 68 | 69 | result = MergeSort.sort( 70 | MergeSort.SPACE_TYPE.IN_PLACE, 71 | reverse.clone()); 72 | assertTrue(check(result)); 73 | } 74 | 75 | @Order(2) 76 | @Test 77 | public void testMergeSortsNotInPlace() { 78 | // Merge sort 79 | Integer[] result = MergeSort.sort( 80 | MergeSort.SPACE_TYPE.NOT_IN_PLACE, 81 | unsorted.clone()); 82 | assertTrue(check(result)); 83 | 84 | result = MergeSort.sort( 85 | MergeSort.SPACE_TYPE.NOT_IN_PLACE, 86 | sorted.clone()); 87 | assertTrue(check(result)); 88 | 89 | result = MergeSort.sort( 90 | MergeSort.SPACE_TYPE.NOT_IN_PLACE, 91 | reverse.clone()); 92 | assertTrue(check(result)); 93 | } 94 | 95 | private static final boolean check(Integer[] array) { 96 | for (int i = 1; i < array.length; i++) { 97 | if (array[i - 1] > array[i]) { 98 | return false; 99 | } 100 | } 101 | 102 | return true; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/NQueensTests.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.algorithm; 2 | 3 | import java.util.List; 4 | import org.junit.jupiter.api.MethodOrderer; 5 | import org.junit.jupiter.api.Order; 6 | import org.junit.jupiter.api.Test; 7 | import org.junit.jupiter.api.TestMethodOrder; 8 | 9 | /** 10 | * NQueens Tests. 11 | * 12 | * @author Way Lau 13 | * @since 2020-10-30 14 | */ 15 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 16 | public class NQueensTests { 17 | 18 | @Order(1) 19 | @Test 20 | public void testMergeSortsInPlace() { 21 | List> result = NQueens.solveNQueens(8); 22 | 23 | for (List list : result) { 24 | System.out.println(list); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/algorithm/QuickSortTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.algorithm; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | import java.util.Random; 8 | import org.junit.jupiter.api.MethodOrderer; 9 | import org.junit.jupiter.api.Order; 10 | import org.junit.jupiter.api.Test; 11 | import org.junit.jupiter.api.TestMethodOrder; 12 | 13 | /** 14 | * QuickSort Test. 15 | * 16 | * @author Way Lau 17 | * @since 2020-10-20 18 | */ 19 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 20 | public class QuickSortTests { 21 | private static final Random RANDOM = new Random(); 22 | 23 | private static final int SIZE = 10000; 24 | 25 | private static Integer[] unsorted = null; // 未排序 26 | 27 | private static Integer[] sorted = null; // 已排序 28 | 29 | private static Integer[] reverse = null; // 反转 30 | 31 | static { 32 | unsorted = new Integer[SIZE]; 33 | int i = 0; 34 | 35 | while (i < unsorted.length) { 36 | int j = RANDOM.nextInt(unsorted.length * 10); 37 | unsorted[i++] = j; 38 | } 39 | 40 | sorted = new Integer[SIZE]; 41 | 42 | for (i = 0; i < sorted.length; i++) { 43 | sorted[i] = i; 44 | } 45 | 46 | reverse = new Integer[SIZE]; 47 | 48 | for (i = (reverse.length - 1); i >= 0; i--) { 49 | reverse[i] = (SIZE - 1) - i; 50 | } 51 | } 52 | 53 | @Order(1) 54 | @Test 55 | public void testQuickSorts() { 56 | // Quicksort 57 | Integer[] result = QuickSort.sort( 58 | QuickSort.PIVOT_TYPE.FIRST, 59 | unsorted.clone()); 60 | assertTrue(check(result)); 61 | 62 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.FIRST, 63 | sorted.clone()); 64 | assertTrue(check(result)); 65 | 66 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.FIRST, 67 | reverse.clone()); 68 | assertTrue(check(result)); 69 | 70 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.MIDDLE, 71 | unsorted.clone()); 72 | assertTrue(check(result)); 73 | 74 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.MIDDLE, 75 | sorted.clone()); 76 | assertTrue(check(result)); 77 | 78 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.MIDDLE, 79 | reverse.clone()); 80 | assertTrue(check(result)); 81 | 82 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.RANDOM, 83 | unsorted.clone()); 84 | assertTrue(check(result)); 85 | 86 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.RANDOM, 87 | sorted.clone()); 88 | assertTrue(check(result)); 89 | 90 | result = QuickSort.sort(QuickSort.PIVOT_TYPE.RANDOM, 91 | reverse.clone()); 92 | assertTrue(check(result)); 93 | } 94 | 95 | private static final boolean check(Integer[] array) { 96 | for (int i = 1; i < array.length; i++) { 97 | if (array[i - 1] > array[i]) 98 | return false; 99 | } 100 | 101 | return true; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/ArrayBinaryTreeTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.junit.jupiter.api.Order; 10 | import org.junit.jupiter.api.Test; 11 | import org.junit.jupiter.api.TestMethodOrder; 12 | import org.junit.jupiter.api.MethodOrderer; 13 | 14 | /** 15 | * ArrayBinaryTree Test. 16 | * 17 | * @since 1.0.0 2020年8月12日 18 | * @author Way Lau 19 | */ 20 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 21 | class ArrayBinaryTreeTest { 22 | @Order(1) 23 | @Test 24 | void testPreOrder() { 25 | Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 }; 26 | List result = new ArrayList( 27 | arr.length); 28 | 29 | ArrayBinaryTree arrBinaryTree = new ArrayBinaryTree<>( 30 | arr); 31 | 32 | arrBinaryTree.preOrder(0, result); 33 | 34 | System.out.println(result); 35 | } 36 | 37 | @Order(2) 38 | @Test 39 | void testInfixOrder() { 40 | Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 }; 41 | List result = new ArrayList( 42 | arr.length); 43 | 44 | ArrayBinaryTree arrBinaryTree = new ArrayBinaryTree<>( 45 | arr); 46 | 47 | arrBinaryTree.infixOrder(0, result); 48 | 49 | System.out.println(result); 50 | } 51 | 52 | @Order(3) 53 | @Test 54 | void testPostOrder() { 55 | Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 }; 56 | List result = new ArrayList( 57 | arr.length); 58 | 59 | ArrayBinaryTree arrBinaryTree = new ArrayBinaryTree<>( 60 | arr); 61 | 62 | arrBinaryTree.postOrder(0, result); 63 | 64 | System.out.println(result); 65 | 66 | } 67 | 68 | @Order(4) 69 | @Test 70 | void testPreOrder2() { 71 | String[] arr = { "A", "B", "C", "D", "E", "F", "G", 72 | "H", "I", "J" }; 73 | 74 | List result = new ArrayList( 75 | arr.length); 76 | 77 | ArrayBinaryTree arrBinaryTree = new ArrayBinaryTree<>( 78 | arr); 79 | 80 | arrBinaryTree.preOrder(0, result); 81 | 82 | System.out.println(result); 83 | 84 | } 85 | 86 | @Order(5) 87 | @Test 88 | void testInfixOrder2() { 89 | String[] arr = { "A", "B", "C", "D", "E", "F", "G", 90 | "H", "I", "J" }; 91 | 92 | List result = new ArrayList( 93 | arr.length); 94 | 95 | ArrayBinaryTree arrBinaryTree = new ArrayBinaryTree<>( 96 | arr); 97 | 98 | arrBinaryTree.infixOrder(0, result); 99 | 100 | System.out.println(result); 101 | } 102 | 103 | @Order(6) 104 | @Test 105 | void testPostOrder2() { 106 | String[] arr = { "A", "B", "C", "D", "E", "F", "G", 107 | "H", "I", "J" }; 108 | 109 | List result = new ArrayList( 110 | arr.length); 111 | 112 | ArrayBinaryTree arrBinaryTree = new ArrayBinaryTree<>( 113 | arr); 114 | 115 | arrBinaryTree.postOrder(0, result); 116 | 117 | System.out.println(result); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/ArrayDequeTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertNull; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | import java.util.ArrayDeque; 12 | import java.util.Deque; 13 | import java.util.NoSuchElementException; 14 | 15 | import org.junit.jupiter.api.Test; 16 | 17 | /** 18 | * ArrayDeque Tests 19 | * 20 | * @since 1.0.0 2020年6月1日 21 | * @author Way Lau 22 | */ 23 | 24 | class ArrayDequeTests { 25 | 26 | @Test 27 | void testAddLast() { 28 | // 初始化队列 29 | Deque queue = new ArrayDeque(3); 30 | 31 | // 测试队列未满时,直接插入没有返回值; 32 | queue.addLast("Java"); 33 | 34 | // 测试队列满则扩容 35 | queue.addLast("C"); 36 | queue.addLast("Python"); 37 | queue.addLast("C++"); // 扩容 38 | } 39 | 40 | @Test 41 | void testOfferLast() { 42 | // 初始化队列 43 | Deque queue = new ArrayDeque(3); 44 | 45 | // 测试队列未满时,返回 true 46 | boolean resultNotFull = queue.offerLast("Java"); 47 | assertTrue(resultNotFull); 48 | 49 | // 测试队列达到容量时,会自动扩容 50 | queue.offerLast("C"); 51 | queue.offerLast("Python"); 52 | boolean resultFull = queue.offerLast("C++"); // 扩容 53 | assertTrue(resultFull); 54 | } 55 | 56 | @Test 57 | void testAddFirst() { 58 | // 初始化队列 59 | Deque queue = new ArrayDeque(3); 60 | 61 | // 测试队列未满时,直接插入没有返回值; 62 | queue.addFirst("Java"); 63 | 64 | // 测试队列满则扩容 65 | queue.addFirst("C"); 66 | queue.addFirst("Python"); 67 | queue.addFirst("C++"); // 扩容 68 | } 69 | 70 | @Test 71 | void testPollFirst() throws InterruptedException { 72 | // 初始化队列 73 | Deque queue = new ArrayDeque(3); 74 | 75 | // 测试队列为空时,返回 null 76 | String resultEmpty = queue.pollFirst(); 77 | assertNull(resultEmpty); 78 | 79 | // 测试队列不为空时,返回队首值并移除 80 | queue.addLast("Java"); 81 | queue.addLast("C"); 82 | queue.addLast("Python"); 83 | String resultNotEmpty = queue.pollFirst(); 84 | assertEquals("Java", resultNotEmpty); 85 | } 86 | 87 | @Test 88 | void testRemoveFirst() throws InterruptedException { 89 | // 初始化队列 90 | Deque queue = new ArrayDeque(3); 91 | 92 | // 测试队列为空时,抛出异常 93 | Throwable excpetion = assertThrows( 94 | NoSuchElementException.class, () -> { 95 | 96 | queue.removeFirst();// 抛异常 97 | 98 | }); 99 | 100 | assertEquals(null, excpetion.getMessage()); 101 | 102 | // 测试队列不为空时,返回队首值并移除 103 | queue.addLast("Java"); 104 | queue.addLast("C"); 105 | queue.addLast("Python"); 106 | String resultNotEmpty = queue.removeFirst(); 107 | assertEquals("Java", resultNotEmpty); 108 | 109 | } 110 | 111 | @Test 112 | void testPeekFirst() throws InterruptedException { 113 | // 初始化队列 114 | 115 | Deque queue = new ArrayDeque(3); 116 | 117 | // 测试队列不为空时,返回队首值并但不移除 118 | queue.add("Java"); 119 | queue.add("C"); 120 | queue.add("Python"); 121 | String resultNotEmpty = queue.peekFirst(); 122 | assertEquals("Java", resultNotEmpty); 123 | resultNotEmpty = queue.peekFirst(); 124 | assertEquals("Java", resultNotEmpty); 125 | resultNotEmpty = queue.peekFirst(); 126 | assertEquals("Java", resultNotEmpty); 127 | 128 | // 测试队列为空时,返回null 129 | queue.clear(); 130 | String resultEmpty = queue.peek(); 131 | assertNull(resultEmpty); 132 | } 133 | 134 | @Test 135 | void testGetFirst() throws InterruptedException { 136 | // 初始化队列 137 | Deque queue = new ArrayDeque(3); 138 | 139 | // 测试队列不为空时,返回队首值并但不移除 140 | queue.add("Java"); 141 | queue.add("C"); 142 | queue.add("Python"); 143 | String resultNotEmpty = queue.getFirst(); 144 | assertEquals("Java", resultNotEmpty); 145 | resultNotEmpty = queue.getFirst(); 146 | assertEquals("Java", resultNotEmpty); 147 | resultNotEmpty = queue.getFirst(); 148 | assertEquals("Java", resultNotEmpty); 149 | 150 | // 测试队列为空时,抛出异常 151 | queue.clear(); 152 | Throwable excpetion = assertThrows( 153 | NoSuchElementException.class, () -> { 154 | queue.getFirst();// 抛异常 155 | }); 156 | assertEquals(null, excpetion.getMessage()); 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/ArrayListTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertNotNull; 9 | import static org.junit.jupiter.api.Assertions.assertThrows; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import org.junit.jupiter.api.Test; 16 | 17 | /** 18 | * ArrayList Test 19 | * 20 | * @since 1.0.0 2020年5月3日 21 | * @author Way Lau 22 | */ 23 | class ArrayListTests { 24 | 25 | @Test 26 | void testSize() { 27 | // 实例化ArrayList 28 | List list = new ArrayList(5); 29 | assertTrue(list.size() == 0); 30 | 31 | list.add("Java"); 32 | assertTrue(list.size() == 1); 33 | } 34 | 35 | @Test 36 | void testIsEmpty() { 37 | // 实例化ArrayList 38 | List list = new ArrayList(5); 39 | assertTrue(list.isEmpty()); 40 | 41 | list.add("Java"); 42 | assertFalse(list.isEmpty()); 43 | } 44 | 45 | @Test 46 | void testContains() { 47 | // 实例化ArrayList 48 | List list = new ArrayList(5); 49 | list.add("Java"); 50 | list.add("C++"); 51 | list.add("C"); 52 | list.add("Python"); 53 | list.add("TypeScript"); 54 | 55 | // 判断存在 56 | assertTrue(list.contains("Java")); 57 | 58 | // 判断不存在 59 | assertFalse(list.contains("Java++")); 60 | } 61 | 62 | @Test 63 | void testAdd() { 64 | // 实例化ArrayList 65 | List list = new ArrayList(5); 66 | list.add(1); 67 | list.add(2); 68 | list.add(3); 69 | list.add(4); 70 | list.add(5); 71 | 72 | // 触发扩容 73 | list.add(6); 74 | 75 | assertTrue(6 == list.size()); 76 | } 77 | 78 | @Test 79 | void testGet() { 80 | // 实例化ArrayList 81 | List list = new ArrayList(5); 82 | list.add("Java"); 83 | list.add("C++"); 84 | list.add("C"); 85 | 86 | // 判断存在 87 | assertEquals("C++", list.get(1)); 88 | 89 | // 判断不存在 90 | Throwable excpetion = assertThrows(IndexOutOfBoundsException.class, () -> { 91 | list.get(4);// 抛异常 92 | }); 93 | 94 | assertNotNull(excpetion.getMessage()); 95 | } 96 | 97 | @Test 98 | void testSet() { 99 | // 实例化ArrayList 100 | List list = new ArrayList(5); 101 | list.add("Java"); 102 | list.add("C++"); 103 | list.add("C"); 104 | 105 | // 判断存在 106 | assertEquals("C", list.set(2, "Python")); 107 | 108 | // 判断不存在 109 | Throwable excpetion = assertThrows(IndexOutOfBoundsException.class, () -> { 110 | list.set(4, "TypeScript");// 抛异常 111 | }); 112 | 113 | assertNotNull(excpetion.getMessage()); 114 | } 115 | 116 | @Test 117 | void testRemove() { 118 | // 实例化ArrayList 119 | List list = new ArrayList(5); 120 | list.add("Java"); 121 | list.add("C++"); 122 | list.add("C"); 123 | 124 | // 判断存在 125 | assertEquals("C", list.remove(2)); 126 | 127 | // 判断不存在 128 | int index = 6; 129 | Throwable excpetion = assertThrows(IndexOutOfBoundsException.class, () -> { 130 | list.remove(index); // 抛异常 131 | }); 132 | 133 | assertNotNull(excpetion.getMessage()); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/ArrayPriorityQueueTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertTrue; 8 | 9 | import java.util.Comparator; 10 | 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * @since 1.0.0 2020年9月14日 15 | * @author Way Lau 16 | */ 17 | 18 | class ArrayPriorityQueueTest { 19 | 20 | @Test 21 | void testComparable() { 22 | // 初始化队列 23 | PriorityQueue queue = new ArrayPriorityQueue( 24 | 3); 25 | 26 | // 添加 27 | // 测试队列未满时,返回 true 28 | boolean resultNotFull = queue.add("Java"); 29 | assertTrue(resultNotFull); 30 | 31 | queue.add("C"); 32 | queue.add("Python"); 33 | 34 | // 删除 35 | String result1 = queue.remove(); 36 | assertEquals(result1, "C"); 37 | 38 | String result2 = queue.remove(); 39 | assertEquals(result2, "Java"); 40 | 41 | String result3 = queue.remove(); 42 | assertEquals(result3, "Python"); 43 | 44 | String result4 = queue.remove(); 45 | assertEquals(result4, null); 46 | } 47 | 48 | @Test 49 | void testUsingComparator() { 50 | int n = 6; 51 | 52 | // 初始化队列 53 | PriorityQueue queue = new ArrayPriorityQueue( 54 | n, new Comparator() { 55 | // 战力由大到小排序 56 | @Override 57 | public int compare(Hero hero0, 58 | Hero hero1) { 59 | return hero1.getPower().compareTo( 60 | hero0.getPower()); 61 | } 62 | }); 63 | 64 | // 添加 65 | queue.add(new Hero("Nemesis", 95)); 66 | queue.add(new Hero("Edifice Rex", 88)); 67 | queue.add(new Hero("Marquis of Death", 91)); 68 | queue.add(new Hero("Magneto", 96)); 69 | queue.add(new Hero("Hulk", 85)); 70 | queue.add(new Hero("Doctor Strange", 94)); 71 | 72 | // 删除 73 | Hero result1 = queue.remove(); 74 | assertEquals(result1, new Hero("Magneto", 96)); 75 | Hero result2 = queue.remove(); 76 | assertEquals(result2, new Hero("Nemesis", 95)); 77 | Hero result3 = queue.remove(); 78 | assertEquals(result3, 79 | new Hero("Doctor Strange", 94)); 80 | Hero result4 = queue.remove(); 81 | assertEquals(result4, 82 | new Hero("Marquis of Death", 91)); 83 | 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/ArrayTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | import java.util.Arrays; 9 | 10 | import org.junit.jupiter.api.Test; 11 | 12 | /** 13 | * Array Test 14 | * 15 | * @since 1.0.0 2020年5月5日 16 | * @author Way Lau 17 | */ 18 | class ArrayTests { 19 | private String[] books = { "《分布式系统常用技术及案例分析》", 20 | "《Spring Boot 企业级应用开发实战》", 21 | "《Spring Cloud 微服务架构开发实战》", 22 | "《Spring 5 开发大全》", 23 | "《Cloud Native 分布式架构原理与实践》", 24 | "《Angular企业级应用开发实战》", 25 | "《大型互联网应用轻量级架构实战》", 26 | "《Java核心编程》", 27 | "《MongoDB+Express+Angular+Node.js全栈开发实战派》", 28 | "《Node.js企业级应用开发实战》", 29 | "《Netty原理解析与开发实战》" }; 30 | 31 | @Test 32 | void testMultiDimArray() { 33 | String[][] names = { { "Mr. ", "Mrs. ", "Ms. " }, 34 | { "Way", "Lau" } }; 35 | 36 | // Mr. Way 37 | assertEquals("Mr. Way", names[0][0] + names[1][0]); 38 | 39 | // Ms. Lau 40 | assertEquals("Ms. Lau", names[0][2] + names[1][1]); 41 | } 42 | 43 | @Test 44 | void testFor() { 45 | System.out.println("老卫作品集:"); 46 | 47 | for (int i = 0; i < books.length; i++) { 48 | System.out.println(books[i]); 49 | } 50 | } 51 | 52 | @Test 53 | void testForEach() { 54 | System.out.println("老卫作品集:"); 55 | 56 | for (String book : books) { 57 | System.out.println(book); 58 | } 59 | } 60 | 61 | @Test 62 | void testCopy() { 63 | String[] oldArray = { "Java", "Python", "C", 64 | "Dart" }; 65 | 66 | // 引用赋值 67 | String[] newArray = oldArray; 68 | 69 | // 改变newArray中的元素 70 | newArray[2] = "C++"; 71 | 72 | // oldArray中的元素也会跟着改变 73 | assertEquals("C++", oldArray[2]); 74 | } 75 | 76 | @Test 77 | void testCopyOf() { 78 | String[] oldArray = { "Java", "Python", "C", 79 | "Dart" }; 80 | 81 | String[] newArray = Arrays.copyOf(oldArray, 82 | oldArray.length); 83 | ; 84 | 85 | // 改变newArray中的元素 86 | newArray[2] = "C++"; 87 | 88 | // oldArray中的元素不会跟着改变 89 | assertEquals("C", oldArray[2]); 90 | 91 | // 新数组扩容为原数组的2倍 92 | @SuppressWarnings("unused") 93 | String[] newArray2 = Arrays.copyOf(oldArray, 94 | oldArray.length * 2); 95 | ; 96 | } 97 | 98 | @Test 99 | void testSort() { 100 | String[] array = { "Java", "Python", "C", "Dart" }; 101 | 102 | System.out.println("排序前:"); 103 | 104 | for (String letter : array) { 105 | System.out.println(letter); 106 | } 107 | 108 | Arrays.sort(array); 109 | 110 | System.out.println("排序后:"); 111 | 112 | for (String letter : array) { 113 | System.out.println(letter); 114 | } 115 | } 116 | 117 | @Test 118 | void testSystemArraycopy() { 119 | String[] oldArray = { "Java", "Python", "C", "Dart", 120 | null }; 121 | 122 | int length = oldArray.length; 123 | 124 | String[] newArray = new String[length]; 125 | 126 | System.arraycopy(oldArray, 0, newArray, 1, 4); 127 | 128 | System.out.println("拷贝后:"); 129 | 130 | for (String letter : newArray) { 131 | System.out.println(letter); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/AvlTreeTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import org.junit.jupiter.api.MethodOrderer; 7 | import org.junit.jupiter.api.Order; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.TestMethodOrder; 10 | 11 | /** 12 | * AVL Tree Test 13 | * 14 | * @since 1.0.0 2020年10月28日 15 | * @author Way Lau 16 | */ 17 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 18 | class AvlTreeTest { 19 | @Order(1) 20 | @Test 21 | void testInsertAndRemove() { 22 | AvlTree tree = new AvlTree(); 23 | 24 | tree.insert(90); 25 | tree.insert(50); 26 | tree.insert(150); 27 | tree.insert(20); 28 | tree.insert(5); 29 | tree.insert(25); 30 | tree.printTree(); 31 | 32 | System.out.println("min node: " + tree.findMin()); 33 | System.out.println("max node: " + tree.findMax()); 34 | 35 | // 删除50 36 | int removed = 50; 37 | tree.remove(removed); 38 | System.out.println("after removed " + removed); 39 | tree.printTree(); 40 | } 41 | 42 | @Order(2) 43 | @Test 44 | void testInsertAndRemove2() { 45 | AvlTree tree = new AvlTree(); 46 | 47 | tree.insert(90); 48 | tree.insert(50); 49 | tree.insert(150); 50 | tree.insert(20); 51 | tree.insert(125); 52 | tree.insert(175); 53 | tree.insert(5); 54 | tree.insert(25); 55 | tree.insert(140); 56 | tree.printTree(); 57 | 58 | System.out.println("min node: " + tree.findMin()); 59 | System.out.println("max node: " + tree.findMax()); 60 | 61 | // 删除50 62 | int removed = 150; 63 | tree.remove(removed); 64 | System.out.println(); 65 | System.out.println("after removed " + removed); 66 | System.out.println(); 67 | tree.printTree(); 68 | } 69 | 70 | @Order(3) 71 | @Test 72 | void testInsertAndRemove3() { 73 | AvlTree tree = new AvlTree(); 74 | 75 | tree.insert(90); 76 | tree.insert(50); 77 | tree.insert(150); 78 | tree.insert(20); 79 | tree.insert(75); 80 | tree.insert(5); 81 | tree.insert(66); 82 | tree.insert(80); 83 | tree.insert(68); 84 | tree.printTree(); 85 | 86 | System.out.println("min node: " + tree.findMin()); 87 | System.out.println("max node: " + tree.findMax()); 88 | 89 | // 删除5 90 | int removed = 5; 91 | tree.remove(removed); 92 | System.out.println(); 93 | System.out.println("after removed " + removed); 94 | System.out.println(); 95 | tree.printTree(); 96 | } 97 | 98 | @Order(4) 99 | @Test 100 | void testPreOrder() { 101 | AvlTree tree = new AvlTree(); 102 | 103 | tree.insert(90); 104 | tree.insert(50); 105 | tree.insert(150); 106 | tree.insert(20); 107 | tree.insert(5); 108 | tree.insert(25); 109 | System.out.println(tree.preOrder()); 110 | } 111 | 112 | @Order(5) 113 | @Test 114 | void testInfixOrder() { 115 | AvlTree tree = new AvlTree(); 116 | 117 | tree.insert(90); 118 | tree.insert(50); 119 | tree.insert(150); 120 | tree.insert(20); 121 | tree.insert(5); 122 | tree.insert(25); 123 | 124 | System.out.println(tree.infixOrder()); 125 | } 126 | 127 | @Order(6) 128 | @Test 129 | void testPostOrder() { 130 | AvlTree tree = new AvlTree(); 131 | 132 | tree.insert(90); 133 | tree.insert(50); 134 | tree.insert(150); 135 | tree.insert(20); 136 | tree.insert(5); 137 | tree.insert(25); 138 | 139 | System.out.println(tree.postOrder()); 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/ConcurrentSkipListMapTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertNotNull; 9 | import static org.junit.jupiter.api.Assertions.assertNull; 10 | import static org.junit.jupiter.api.Assertions.assertThrows; 11 | import static org.junit.jupiter.api.Assertions.assertTrue; 12 | import java.util.Map; 13 | import java.util.concurrent.ConcurrentSkipListMap; 14 | 15 | import org.junit.jupiter.api.Test; 16 | 17 | /** 18 | * ConcurrentSkipListMap Tests 19 | * 20 | * @since 1.0.0 2020年6月14日 21 | * @author Way Lau 22 | */ 23 | class ConcurrentSkipListMapTests { 24 | @Test 25 | void testPut() throws InterruptedException { 26 | // 初始化Map 27 | Map map = new ConcurrentSkipListMap(); 28 | // 测试键之前没有关联值 29 | String resultEmpty = map.put("id001", "Java"); 30 | assertNull(resultEmpty); 31 | 32 | // 测试键之前有关联值 33 | String resultNotEmpty = map.put("id001", "C"); 34 | assertEquals(resultNotEmpty, "Java"); 35 | 36 | // 测试键关联null值,抛出NullPointerException 37 | Throwable excpetion = assertThrows( 38 | NullPointerException.class, () -> { 39 | map.put("id001", null);// 抛出NullPointerException异常 40 | }); 41 | 42 | assertNotNull(excpetion); 43 | } 44 | 45 | @Test 46 | void testGet() throws InterruptedException { 47 | // 初始化Map 48 | Map map = new ConcurrentSkipListMap(); 49 | 50 | map.put("id001", "Java"); 51 | map.put("id002", "C"); 52 | map.put("id003", "Python"); 53 | 54 | // 测试Map有映射值时,返回映射值 55 | String result = map.get("id001"); 56 | assertEquals(result, "Java"); 57 | 58 | // 测试Map无映射值时,返回null 59 | String resultNull = map.get("no exist"); 60 | assertNull(resultNull); 61 | } 62 | 63 | @Test 64 | void testSize() { 65 | // 初始化Map 66 | Map map = new ConcurrentSkipListMap(); 67 | 68 | map.put("id001", "Java"); 69 | map.put("id002", "C"); 70 | map.put("id003", "Python"); 71 | 72 | // 测试Map有映射值时 73 | int result = map.size(); 74 | assertTrue(result == 3); 75 | } 76 | 77 | @Test 78 | void testIsEmpty() { 79 | // 初始化Map 80 | Map map = new ConcurrentSkipListMap(); 81 | 82 | // 测试Map无映射值时 83 | boolean resultEmpty = map.isEmpty(); 84 | assertTrue(resultEmpty); 85 | 86 | // 测试Map有映射值时 87 | map.put("id001", "Java"); 88 | map.put("id002", "C"); 89 | map.put("id003", "Python"); 90 | boolean resultNotEmpty = map.isEmpty(); 91 | assertFalse(resultNotEmpty); 92 | } 93 | 94 | @Test 95 | void testContainsKey() { 96 | // 初始化Map 97 | Map map = new ConcurrentSkipListMap(); 98 | 99 | // 测试Map无映射值时 100 | boolean resultEmpty = map.containsKey("id001"); 101 | assertFalse(resultEmpty); 102 | 103 | // 测试Map有映射值时 104 | map.put("id001", "Java"); 105 | map.put("id002", "C"); 106 | map.put("id003", "Python"); 107 | boolean resultNotEmpty = map.containsKey("id001"); 108 | assertTrue(resultNotEmpty); 109 | } 110 | 111 | @Test 112 | void testContainsValue() { 113 | // 初始化Map 114 | Map map = new ConcurrentSkipListMap(); 115 | 116 | // 测试Map无映射值时 117 | boolean resultEmpty = map.containsValue("Java"); 118 | assertFalse(resultEmpty); 119 | 120 | // 测试Map有映射值时 121 | map.put("id001", "Java"); 122 | map.put("id002", "C"); 123 | map.put("id003", "Python"); 124 | boolean resultNotEmpty = map.containsValue("Java"); 125 | assertTrue(resultNotEmpty); 126 | } 127 | 128 | @Test 129 | void testRemove() { 130 | // 初始化Map 131 | Map map = new ConcurrentSkipListMap(); 132 | 133 | // 测试Map无映射值时 134 | String resultEmpty = map.remove("id001"); 135 | assertNull(resultEmpty); 136 | 137 | // 测试Map有映射值时 138 | map.put("id001", "Java"); 139 | map.put("id002", "C"); 140 | map.put("id003", "Python"); 141 | String resultNotEmpty = map.remove("id001"); 142 | assertEquals(resultNotEmpty, "Java"); 143 | 144 | // 测试Map无映射值时 145 | String resultEmpty2 = map.remove("id001"); 146 | assertNull(resultEmpty2); 147 | } 148 | 149 | @Test 150 | void testClear() { 151 | // 初始化Map 152 | Map map = new ConcurrentSkipListMap(); 153 | map.put("id001", "Java"); 154 | map.put("id002", "C"); 155 | map.put("id003", "Python"); 156 | 157 | // 测试Map有映射值时 158 | int result = map.size(); 159 | assertTrue(result == 3); 160 | 161 | // 测试Map无映射值时 162 | map.clear(); 163 | result = map.size(); 164 | assertTrue(result == 0); 165 | } 166 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/DictionaryTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | /** 7 | * Dictionary Test. 8 | * 9 | * @since 1.0.0 2020年5月31日 10 | * @author Way Lau 11 | */ 12 | class DictionaryTests { 13 | 14 | /** 15 | * 16 | */ 17 | public DictionaryTests() { 18 | // TODO Auto-generated constructor stub 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/GraphBreadthFirstTraversalTests.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.jupiter.api.MethodOrderer; 6 | import org.junit.jupiter.api.Order; 7 | import org.junit.jupiter.api.Test; 8 | import org.junit.jupiter.api.TestMethodOrder; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | import java.util.ArrayList; 13 | 14 | import com.waylau.java.demo.datastructure.Graph.Edge; 15 | import com.waylau.java.demo.datastructure.Graph.Vertex; 16 | 17 | /** 18 | * Graph Breadth First Traversal Tests 19 | * 20 | * @since 1.0.0 2020年10月28日 21 | * @author Way Lau 22 | */ 23 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 24 | class GraphBreadthFirstTraversalTests { 25 | // 无向图 26 | private static class UndirectedGraph { 27 | final List> verticies = new ArrayList>(); 28 | final Graph.Vertex v1 = new Graph.Vertex( 29 | 1); 30 | final Graph.Vertex v2 = new Graph.Vertex( 31 | 2); 32 | final Graph.Vertex v3 = new Graph.Vertex( 33 | 3); 34 | final Graph.Vertex v4 = new Graph.Vertex( 35 | 4); 36 | final Graph.Vertex v5 = new Graph.Vertex( 37 | 5); 38 | final Graph.Vertex v6 = new Graph.Vertex( 39 | 6); 40 | final Graph.Vertex v7 = new Graph.Vertex( 41 | 7); 42 | final Graph.Vertex v8 = new Graph.Vertex( 43 | 8); 44 | { 45 | verticies.add(v1); 46 | verticies.add(v2); 47 | verticies.add(v3); 48 | verticies.add(v4); 49 | verticies.add(v5); 50 | verticies.add(v6); 51 | verticies.add(v7); 52 | verticies.add(v8); 53 | } 54 | 55 | final List> edges = new ArrayList>(); 56 | final Graph.Edge e1_2 = new Graph.Edge( 57 | 7, v1, v2); 58 | final Graph.Edge e1_3 = new Graph.Edge( 59 | 9, v1, v3); 60 | final Graph.Edge e1_6 = new Graph.Edge( 61 | 14, v1, v6); 62 | final Graph.Edge e2_3 = new Graph.Edge( 63 | 10, v2, v3); 64 | final Graph.Edge e2_4 = new Graph.Edge( 65 | 15, v2, v4); 66 | final Graph.Edge e3_4 = new Graph.Edge( 67 | 11, v3, v4); 68 | final Graph.Edge e3_6 = new Graph.Edge( 69 | 2, v3, v6); 70 | final Graph.Edge e5_6 = new Graph.Edge( 71 | 9, v5, v6); 72 | final Graph.Edge e4_5 = new Graph.Edge( 73 | 6, v4, v5); 74 | final Graph.Edge e1_7 = new Graph.Edge( 75 | 1, v1, v7); 76 | final Graph.Edge e1_8 = new Graph.Edge( 77 | 1, v1, v8); 78 | { 79 | edges.add(e1_2); 80 | edges.add(e1_3); 81 | edges.add(e1_6); 82 | edges.add(e2_3); 83 | edges.add(e2_4); 84 | edges.add(e3_4); 85 | edges.add(e3_6); 86 | edges.add(e5_6); 87 | edges.add(e4_5); 88 | edges.add(e1_7); 89 | edges.add(e1_8); 90 | } 91 | 92 | final Graph graph = new Graph( 93 | verticies, edges); 94 | } 95 | 96 | @Order(1) 97 | @Test 98 | void testBreadthFirstTraversal() { 99 | final UndirectedGraph undirected = new UndirectedGraph(); 100 | 101 | final Graph.Vertex[] result = 102 | 103 | GraphBreadthFirstTraversal 104 | .breadthFirstTraversal( 105 | undirected.graph, 106 | undirected.v2); 107 | 108 | assertTrue(result[0].getValue() == 2); 109 | assertTrue(result[1].getValue() == 1); 110 | assertTrue(result[2].getValue() == 3); 111 | assertTrue(result[3].getValue() == 4); 112 | assertTrue(result[4].getValue() == 6); 113 | assertTrue(result[5].getValue() == 7); 114 | assertTrue(result[6].getValue() == 8); 115 | assertTrue(result[7].getValue() == 5); 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/GraphDepthFirstTraversalTests.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.jupiter.api.MethodOrderer; 6 | import org.junit.jupiter.api.Order; 7 | import org.junit.jupiter.api.Test; 8 | import org.junit.jupiter.api.TestMethodOrder; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | import java.util.ArrayList; 13 | 14 | import com.waylau.java.demo.datastructure.Graph.Edge; 15 | import com.waylau.java.demo.datastructure.Graph.Vertex; 16 | 17 | /** 18 | * Graph Depth First Traversal Tests 19 | * 20 | * @since 1.0.0 2020年10月28日 21 | * @author Way Lau 22 | */ 23 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 24 | class GraphDepthFirstTraversalTests { 25 | // 无向图 26 | private static class UndirectedGraph { 27 | final List> verticies = new ArrayList>(); 28 | final Graph.Vertex v1 = new Graph.Vertex( 29 | 1); 30 | final Graph.Vertex v2 = new Graph.Vertex( 31 | 2); 32 | final Graph.Vertex v3 = new Graph.Vertex( 33 | 3); 34 | final Graph.Vertex v4 = new Graph.Vertex( 35 | 4); 36 | final Graph.Vertex v5 = new Graph.Vertex( 37 | 5); 38 | final Graph.Vertex v6 = new Graph.Vertex( 39 | 6); 40 | final Graph.Vertex v7 = new Graph.Vertex( 41 | 7); 42 | final Graph.Vertex v8 = new Graph.Vertex( 43 | 8); 44 | { 45 | verticies.add(v1); 46 | verticies.add(v2); 47 | verticies.add(v3); 48 | verticies.add(v4); 49 | verticies.add(v5); 50 | verticies.add(v6); 51 | verticies.add(v7); 52 | verticies.add(v8); 53 | } 54 | 55 | final List> edges = new ArrayList>(); 56 | final Graph.Edge e1_2 = new Graph.Edge( 57 | 7, v1, v2); 58 | final Graph.Edge e1_3 = new Graph.Edge( 59 | 9, v1, v3); 60 | final Graph.Edge e1_6 = new Graph.Edge( 61 | 14, v1, v6); 62 | final Graph.Edge e2_3 = new Graph.Edge( 63 | 10, v2, v3); 64 | final Graph.Edge e2_4 = new Graph.Edge( 65 | 15, v2, v4); 66 | final Graph.Edge e3_4 = new Graph.Edge( 67 | 11, v3, v4); 68 | final Graph.Edge e3_6 = new Graph.Edge( 69 | 2, v3, v6); 70 | final Graph.Edge e5_6 = new Graph.Edge( 71 | 9, v5, v6); 72 | final Graph.Edge e4_5 = new Graph.Edge( 73 | 6, v4, v5); 74 | final Graph.Edge e1_7 = new Graph.Edge( 75 | 1, v1, v7); 76 | final Graph.Edge e1_8 = new Graph.Edge( 77 | 1, v1, v8); 78 | { 79 | edges.add(e1_2); 80 | edges.add(e1_3); 81 | edges.add(e1_6); 82 | edges.add(e2_3); 83 | edges.add(e2_4); 84 | edges.add(e3_4); 85 | edges.add(e3_6); 86 | edges.add(e5_6); 87 | edges.add(e4_5); 88 | edges.add(e1_7); 89 | edges.add(e1_8); 90 | } 91 | 92 | final Graph graph = new Graph( 93 | verticies, edges); 94 | } 95 | 96 | @Order(1) 97 | @Test 98 | void testDepthFirstTraversal() { 99 | final UndirectedGraph undirected = new UndirectedGraph(); 100 | 101 | final Graph.Vertex[] result = GraphDepthFirstTraversal 102 | .depthFirstTraversal(undirected.graph, 103 | undirected.v2); 104 | 105 | assertTrue(result[0].getValue() == 2); 106 | assertTrue(result[1].getValue() == 1); 107 | assertTrue(result[2].getValue() == 3); 108 | assertTrue(result[3].getValue() == 4); 109 | assertTrue(result[4].getValue() == 5); 110 | assertTrue(result[5].getValue() == 6); 111 | assertTrue(result[6].getValue() == 7); 112 | assertTrue(result[7].getValue() == 8); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/HashMapTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertNull; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | import org.junit.jupiter.api.Test; 15 | 16 | /** 17 | * HashMap Tests 18 | * 19 | * @since 1.0.0 2020年6月4日 20 | * @author Way Lau 21 | */ 22 | class HashMapTests { 23 | @Test 24 | void testPut() throws InterruptedException { 25 | // 初始化Map 26 | Map map = 27 | new HashMap(3); 28 | // 测试键之前没有关联值 29 | String resultEmpty = map.put("id001", "Java"); 30 | assertNull(resultEmpty); 31 | 32 | // 测试键之前有关联值 33 | String resultNotEmpty = map.put("id001", "C"); 34 | assertEquals(resultNotEmpty, "Java"); 35 | 36 | // 测试键关联null值 37 | String resultNull = map.put("id001", null); 38 | assertEquals(resultNull, "C"); 39 | } 40 | 41 | @Test 42 | void testGet() throws InterruptedException { 43 | // 初始化Map 44 | Map map = 45 | new HashMap(3); 46 | 47 | map.put("id001", "Java"); 48 | map.put("id002", "C"); 49 | map.put("id003", "Python"); 50 | 51 | // 测试Map有映射值时,返回映射值 52 | String result = map.get("id001"); 53 | assertEquals(result, "Java"); 54 | 55 | // 测试Map无映射值时,返回null 56 | String resultNull = map.get("no exist"); 57 | assertNull(resultNull); 58 | } 59 | 60 | @Test 61 | void testSize() { 62 | // 初始化Map 63 | Map map = 64 | new HashMap(3); 65 | 66 | map.put("id001", "Java"); 67 | map.put("id002", "C"); 68 | map.put("id003", "Python"); 69 | 70 | // 测试Map有映射值时 71 | int result = map.size(); 72 | assertTrue(result == 3); 73 | } 74 | 75 | @Test 76 | void testIsEmpty() { 77 | // 初始化Map 78 | Map map = 79 | new HashMap(3); 80 | 81 | // 测试Map无映射值时 82 | boolean resultEmpty = map.isEmpty(); 83 | assertTrue(resultEmpty); 84 | 85 | // 测试Map有映射值时 86 | map.put("id001", "Java"); 87 | map.put("id002", "C"); 88 | map.put("id003", "Python"); 89 | boolean resultNotEmpty = map.isEmpty(); 90 | assertFalse(resultNotEmpty); 91 | } 92 | 93 | @Test 94 | void testContainsKey() { 95 | // 初始化Map 96 | Map map = 97 | new HashMap(3); 98 | 99 | // 测试Map无映射值时 100 | boolean resultEmpty = map.containsKey("id001"); 101 | assertFalse(resultEmpty); 102 | 103 | // 测试Map有映射值时 104 | map.put("id001", "Java"); 105 | map.put("id002", "C"); 106 | map.put("id003", "Python"); 107 | boolean resultNotEmpty = map.containsKey("id001"); 108 | assertTrue(resultNotEmpty); 109 | } 110 | 111 | @Test 112 | void testContainsValue() { 113 | // 初始化Map 114 | Map map = 115 | new HashMap(3); 116 | 117 | // 测试Map无映射值时 118 | boolean resultEmpty = map.containsValue("Java"); 119 | assertFalse(resultEmpty); 120 | 121 | // 测试Map有映射值时 122 | map.put("id001", "Java"); 123 | map.put("id002", "C"); 124 | map.put("id003", "Python"); 125 | boolean resultNotEmpty = map.containsValue("Java"); 126 | assertTrue(resultNotEmpty); 127 | } 128 | 129 | 130 | @Test 131 | void testRemove() { 132 | // 初始化Map 133 | Map map = 134 | new HashMap(3); 135 | 136 | // 测试Map无映射值时 137 | String resultEmpty = map.remove("id001"); 138 | assertNull(resultEmpty); 139 | 140 | // 测试Map有映射值时 141 | map.put("id001", "Java"); 142 | map.put("id002", "C"); 143 | map.put("id003", "Python"); 144 | String resultNotEmpty = map.remove("id001"); 145 | assertEquals(resultNotEmpty, "Java"); 146 | 147 | // 测试Map无映射值时 148 | String resultEmpty2 = map.remove("id001"); 149 | assertNull(resultEmpty2); 150 | } 151 | 152 | 153 | @Test 154 | void testClear() { 155 | // 初始化Map 156 | Map map = 157 | new HashMap(3); 158 | map.put("id001", "Java"); 159 | map.put("id002", "C"); 160 | map.put("id003", "Python"); 161 | 162 | // 测试Map有映射值时 163 | int result = map.size(); 164 | assertTrue(result == 3); 165 | 166 | // 测试Map无映射值时 167 | map.clear(); 168 | result = map.size(); 169 | assertTrue(result == 0); 170 | } 171 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/HeapPriorityQueueTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertTrue; 9 | 10 | import java.util.Comparator; 11 | 12 | import org.junit.jupiter.api.Test; 13 | 14 | /** 15 | * HeapPriorityQueue Test 16 | * 17 | * @since 1.0.0 2020年9月11日 18 | * @author Way Lau 19 | */ 20 | class HeapPriorityQueueTest { 21 | 22 | @Test 23 | void testComparable() { 24 | // 初始化队列 25 | PriorityQueue queue = new HeapPriorityQueue( 26 | 3); 27 | 28 | // 添加 29 | // 测试队列未满时,返回 true 30 | boolean resultNotFull = queue.add("Java"); 31 | assertTrue(resultNotFull); 32 | 33 | queue.add("C"); 34 | queue.add("Python"); 35 | 36 | // 删除 37 | String result1 = queue.remove(); 38 | assertEquals(result1, "C"); 39 | 40 | String result2 = queue.remove(); 41 | assertEquals(result2, "Java"); 42 | 43 | String result3 = queue.remove(); 44 | assertEquals(result3, "Python"); 45 | 46 | String result4 = queue.remove(); 47 | assertEquals(result4, null); 48 | } 49 | 50 | @Test 51 | void testUsingComparator() { 52 | int n = 6; 53 | 54 | // 初始化队列 55 | PriorityQueue queue = new HeapPriorityQueue( 56 | n, new Comparator() { 57 | // 战力由大到小排序 58 | 59 | @Override 60 | public int compare(Hero hero0, 61 | Hero hero1) { 62 | return hero1.getPower().compareTo( 63 | hero0.getPower()); 64 | } 65 | }); 66 | 67 | // 添加 68 | queue.add(new Hero("Nemesis", 95)); 69 | queue.add(new Hero("Edifice Rex", 88)); 70 | queue.add(new Hero("Marquis of Death", 91)); 71 | queue.add(new Hero("Magneto", 96)); 72 | queue.add(new Hero("Hulk", 85)); 73 | queue.add(new Hero("Doctor Strange", 94)); 74 | 75 | // 删除 76 | Hero result1 = queue.remove(); 77 | assertEquals(result1, new Hero("Magneto", 96)); 78 | Hero result2 = queue.remove(); 79 | assertEquals(result2, new Hero("Nemesis", 95)); 80 | Hero result3 = queue.remove(); 81 | assertEquals(result3, 82 | new Hero("Doctor Strange", 94)); 83 | Hero result4 = queue.remove(); 84 | assertEquals(result4, 85 | new Hero("Marquis of Death", 91)); 86 | Hero result5 = queue.remove(); 87 | assertEquals(result5, new Hero("Edifice Rex", 88)); 88 | Hero result6 = queue.remove(); 89 | assertEquals(result6, new Hero("Hulk", 85)); 90 | Hero result7 = queue.remove(); 91 | assertEquals(result7, null); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/HuffmanTreeTest.java: -------------------------------------------------------------------------------- 1 | package com.waylau.java.demo.datastructure; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import org.junit.jupiter.api.MethodOrderer; 7 | import org.junit.jupiter.api.Order; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.TestMethodOrder; 10 | 11 | 12 | 13 | /** 14 | * HuffmanTree Test. 15 | * 16 | * @since 1.0.0 2020年9月8日 17 | * @author Way Lau 18 | */ 19 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 20 | class HuffmanTreeTest { 21 | @Order(1) 22 | @Test 23 | void test() { 24 | List> list = new ArrayList>(); 25 | list.add(new HuffmanTreeNode("A", 0.1)); 26 | list.add(new HuffmanTreeNode("B", 0.13)); 27 | list.add(new HuffmanTreeNode("C", 0.28)); 28 | list.add(new HuffmanTreeNode("D", 0.49)); 29 | 30 | HuffmanTreeNode root = HuffmanTree.createTree(list); 31 | HuffmanTree.encode(root); 32 | 33 | System.out.println(HuffmanTree.breadth(root)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/LinkedBinarySearchTreeTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import org.junit.jupiter.api.MethodOrderer; 7 | import org.junit.jupiter.api.Order; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.TestMethodOrder; 10 | 11 | /** 12 | * LinkedBinarySearchTree Test 13 | * 14 | * @author Way Lau 15 | * @since 2020-09-26 16 | */ 17 | 18 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 19 | class LinkedBinarySearchTreeTests { 20 | @Order(1) 21 | @Test 22 | void testInsertAndRemove() { 23 | LinkedBinarySearchTree tree = new LinkedBinarySearchTree(); 24 | 25 | tree.insert(90); 26 | tree.insert(50); 27 | tree.insert(150); 28 | tree.insert(20); 29 | tree.insert(5); 30 | tree.insert(25); 31 | tree.print(); 32 | 33 | System.out.println("min node: " + tree.findMin()); 34 | System.out.println("max node: " + tree.findMax()); 35 | 36 | // 删除50 37 | int removed = 50; 38 | tree.remove(removed); 39 | System.out.println(); 40 | System.out.println("after removed " + removed); 41 | System.out.println(); 42 | tree.print(); 43 | } 44 | 45 | @Order(2) 46 | @Test 47 | void testInsertAndRemove2() { 48 | LinkedBinarySearchTree tree = new LinkedBinarySearchTree(); 49 | 50 | tree.insert(90); 51 | tree.insert(50); 52 | tree.insert(150); 53 | tree.insert(20); 54 | tree.insert(125); 55 | tree.insert(175); 56 | tree.insert(5); 57 | tree.insert(25); 58 | tree.insert(140); 59 | 60 | tree.print(); 61 | 62 | System.out.println("min node: " + tree.findMin()); 63 | System.out.println("max node: " + tree.findMax()); 64 | 65 | // 删除150 66 | int removed = 150; 67 | tree.remove(removed); 68 | System.out.println(); 69 | System.out.println("after removed " + removed); 70 | System.out.println(); 71 | 72 | tree.print(); 73 | } 74 | 75 | @Order(3) 76 | @Test 77 | void testInsertAndRemove3() { 78 | LinkedBinarySearchTree tree = new LinkedBinarySearchTree(); 79 | 80 | tree.insert(90); 81 | tree.insert(50); 82 | tree.insert(150); 83 | tree.insert(20); 84 | tree.insert(75); 85 | tree.insert(5); 86 | tree.insert(66); 87 | tree.insert(80); 88 | tree.insert(68); 89 | 90 | tree.print(); 91 | 92 | System.out.println("min node: " + tree.findMin()); 93 | System.out.println("max node: " + tree.findMax()); 94 | 95 | // 删除50 96 | int removed = 50; 97 | tree.remove(removed); 98 | System.out.println(); 99 | System.out.println("after removed " + removed); 100 | System.out.println(); 101 | 102 | tree.print(); 103 | } 104 | 105 | @Order(4) 106 | @Test 107 | void testPreOrder() { 108 | LinkedBinarySearchTree tree = new LinkedBinarySearchTree(); 109 | 110 | tree.insert(90); 111 | tree.insert(50); 112 | tree.insert(150); 113 | tree.insert(20); 114 | tree.insert(5); 115 | tree.insert(25); 116 | 117 | System.out.println(tree.preOrder()); 118 | } 119 | 120 | @Order(5) 121 | @Test 122 | void testInfixOrder() { 123 | LinkedBinarySearchTree tree = new LinkedBinarySearchTree(); 124 | 125 | tree.insert(90); 126 | tree.insert(50); 127 | tree.insert(150); 128 | tree.insert(20); 129 | tree.insert(5); 130 | tree.insert(25); 131 | 132 | System.out.println(tree.infixOrder()); 133 | } 134 | 135 | @Order(6) 136 | @Test 137 | void testPostOrder() { 138 | LinkedBinarySearchTree tree = new LinkedBinarySearchTree(); 139 | 140 | tree.insert(90); 141 | tree.insert(50); 142 | tree.insert(150); 143 | tree.insert(20); 144 | tree.insert(5); 145 | tree.insert(25); 146 | 147 | System.out.println(tree.postOrder()); 148 | } 149 | 150 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/LinkedBinaryTreeTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import org.junit.jupiter.api.Order; 9 | import org.junit.jupiter.api.Test; 10 | import org.junit.jupiter.api.TestMethodOrder; 11 | import org.junit.jupiter.api.MethodOrderer; 12 | 13 | /** 14 | * LinkedBinaryTree Test. 15 | * 16 | * @since 1.0.0 2020年8月13日 17 | * @author Way Lau 18 | */ 19 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 20 | class LinkedBinaryTreeTest { 21 | @Order(1) 22 | @Test 23 | void testPreOrder() { 24 | BinaryTreeNode nodeF = new BinaryTreeNode<>( 25 | "F"); 26 | BinaryTreeNode nodeG = new BinaryTreeNode<>( 27 | "G"); 28 | BinaryTreeNode nodeH = new BinaryTreeNode<>( 29 | "H"); 30 | BinaryTreeNode nodeI = new BinaryTreeNode<>( 31 | "I"); 32 | BinaryTreeNode nodeJ = new BinaryTreeNode<>( 33 | "J"); 34 | BinaryTreeNode nodeD = new BinaryTreeNode<>( 35 | "D", nodeH, nodeI); 36 | BinaryTreeNode nodeE = new BinaryTreeNode<>( 37 | "E", nodeJ, null); 38 | BinaryTreeNode nodeB = new BinaryTreeNode<>( 39 | "B", nodeD, nodeE); 40 | BinaryTreeNode nodeC = new BinaryTreeNode<>( 41 | "C", nodeF, nodeG); 42 | BinaryTreeNode nodeA = new BinaryTreeNode<>( 43 | "A", nodeB, nodeC); // 根节点 44 | 45 | List result = new ArrayList(); 46 | 47 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 48 | linkedBinaryTree.preOrder(nodeA, result); 49 | System.out.println(result); 50 | 51 | } 52 | 53 | @Order(2) 54 | @Test 55 | void testInfixOrder() { 56 | BinaryTreeNode nodeF = new BinaryTreeNode<>( 57 | "F"); 58 | BinaryTreeNode nodeG = new BinaryTreeNode<>( 59 | "G"); 60 | BinaryTreeNode nodeH = new BinaryTreeNode<>( 61 | "H"); 62 | BinaryTreeNode nodeI = new BinaryTreeNode<>( 63 | "I"); 64 | BinaryTreeNode nodeJ = new BinaryTreeNode<>( 65 | "J"); 66 | BinaryTreeNode nodeD = new BinaryTreeNode<>( 67 | "D", nodeH, nodeI); 68 | BinaryTreeNode nodeE = new BinaryTreeNode<>( 69 | "E", nodeJ, null); 70 | BinaryTreeNode nodeB = new BinaryTreeNode<>( 71 | "B", nodeD, nodeE); 72 | BinaryTreeNode nodeC = new BinaryTreeNode<>( 73 | "C", nodeF, nodeG); 74 | BinaryTreeNode nodeA = new BinaryTreeNode<>( 75 | "A", nodeB, nodeC); // 根节点 76 | 77 | List result = new ArrayList(); 78 | 79 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 80 | linkedBinaryTree.infixOrder(nodeA, result); 81 | System.out.println(result); 82 | } 83 | 84 | @Order(3) 85 | @Test 86 | void testPostOrder() { 87 | BinaryTreeNode nodeF = new BinaryTreeNode<>( 88 | "F"); 89 | BinaryTreeNode nodeG = new BinaryTreeNode<>( 90 | "G"); 91 | BinaryTreeNode nodeH = new BinaryTreeNode<>( 92 | "H"); 93 | BinaryTreeNode nodeI = new BinaryTreeNode<>( 94 | "I"); 95 | BinaryTreeNode nodeJ = new BinaryTreeNode<>( 96 | "J"); 97 | BinaryTreeNode nodeD = new BinaryTreeNode<>( 98 | "D", nodeH, nodeI); 99 | BinaryTreeNode nodeE = new BinaryTreeNode<>( 100 | "E", nodeJ, null); 101 | BinaryTreeNode nodeB = new BinaryTreeNode<>( 102 | "B", nodeD, nodeE); 103 | BinaryTreeNode nodeC = new BinaryTreeNode<>( 104 | "C", nodeF, nodeG); 105 | BinaryTreeNode nodeA = new BinaryTreeNode<>( 106 | "A", nodeB, nodeC); // 根节点 107 | 108 | List result = new ArrayList(); 109 | 110 | LinkedBinaryTree linkedBinaryTree = new LinkedBinaryTree<>(); 111 | linkedBinaryTree.postOrder(nodeA, result); 112 | System.out.println(result); 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/LinkedListTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertNotNull; 9 | import static org.junit.jupiter.api.Assertions.assertThrows; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | 15 | import org.junit.jupiter.api.Test; 16 | 17 | /** 18 | * LinkedList Test. 19 | * 20 | * @since 1.0.0 2020年5月4日 21 | * @author Way Lau 22 | */ 23 | class LinkedListTests { 24 | 25 | @Test 26 | void testSize() { 27 | // 实例化LinkedList 28 | List list = new LinkedList(); 29 | assertTrue(list.size() == 0); 30 | 31 | list.add("Java"); 32 | assertTrue(list.size() == 1); 33 | } 34 | 35 | @Test 36 | void testIsEmpty() { 37 | // 实例化LinkedList 38 | List list = new LinkedList(); 39 | assertTrue(list.isEmpty()); 40 | 41 | list.add("Java"); 42 | assertFalse(list.isEmpty()); 43 | } 44 | 45 | @Test 46 | void testContains() { 47 | // 实例化LinkedList 48 | List list = new LinkedList(); 49 | list.add("Java"); 50 | list.add("C++"); 51 | list.add("C"); 52 | list.add("Python"); 53 | list.add("TypeScript"); 54 | 55 | // 判断存在 56 | assertTrue(list.contains("Java")); 57 | 58 | // 判断不存在 59 | assertFalse(list.contains("Java++")); 60 | } 61 | 62 | @Test 63 | void testAdd() { 64 | // 实例化LinkedList 65 | List list = new LinkedList(); 66 | list.add(1); 67 | list.add(2); 68 | list.add(3); 69 | list.add(4); 70 | list.add(5); 71 | 72 | assertFalse(list.isEmpty()); 73 | } 74 | 75 | @Test 76 | void testGet() { 77 | // 实例化LinkedList 78 | List list = new LinkedList(); 79 | list.add("Java"); 80 | list.add("C++"); 81 | list.add("C"); 82 | 83 | // 判断存在 84 | assertEquals("C++", list.get(1)); 85 | 86 | // 判断不存在 87 | int index = 6; 88 | Throwable excpetion = assertThrows( 89 | IndexOutOfBoundsException.class, () -> { 90 | list.get(index);// 抛异常 91 | }); 92 | 93 | assertNotNull(excpetion.getMessage()); 94 | } 95 | 96 | @Test 97 | void testSet() { 98 | // 实例化LinkedList 99 | List list = new LinkedList(); 100 | list.add("Java"); 101 | list.add("C++"); 102 | list.add("C"); 103 | 104 | // 判断存在 105 | assertEquals("C", list.set(2, "Python")); 106 | 107 | // 判断不存在 108 | int index = 6; 109 | Throwable excpetion = assertThrows( 110 | IndexOutOfBoundsException.class, () -> { 111 | list.set(index, "Python");// 抛异常 112 | }); 113 | 114 | assertNotNull(excpetion.getMessage()); 115 | } 116 | 117 | @Test 118 | void testRemove() { 119 | // 实例化LinkedList 120 | List list = new LinkedList(); 121 | list.add("Java"); 122 | list.add("C++"); 123 | list.add("C"); 124 | 125 | // 判断存在 126 | assertEquals("C", list.remove(2)); 127 | 128 | assertEquals("Java", list.get(0)); 129 | assertEquals("C++", list.get(1)); 130 | 131 | // 判断不存在 132 | int index = 6; 133 | Throwable excpetion = assertThrows( 134 | IndexOutOfBoundsException.class, () -> { 135 | list.remove(index); // 抛异常 136 | }); 137 | 138 | assertNotNull(excpetion.getMessage()); 139 | } 140 | 141 | @Test 142 | void testAddFirst() { 143 | // 实例化LinkedList 144 | LinkedList list = new LinkedList(); 145 | list.addFirst("Java"); 146 | list.addFirst("C++"); 147 | list.addFirst("C"); 148 | 149 | // 判断存在 150 | assertEquals("C", list.get(0)); 151 | assertEquals("C++", list.get(1)); 152 | assertEquals("Java", list.get(2)); 153 | } 154 | 155 | @Test 156 | void testAddLast() { 157 | // 实例化LinkedList 158 | LinkedList list = new LinkedList(); 159 | list.addLast("Java"); 160 | list.addLast("C++"); 161 | list.addLast("C"); 162 | 163 | // 判断存在 164 | assertEquals("Java", list.get(0)); 165 | assertEquals("C++", list.get(1)); 166 | assertEquals("C", list.get(2)); 167 | } 168 | 169 | @Test 170 | void testRemoveFirst() { 171 | // 实例化LinkedList 172 | LinkedList list = new LinkedList(); 173 | list.add("Java"); 174 | list.add("C++"); 175 | list.add("C"); 176 | 177 | // 判断存在 178 | assertEquals("Java", list.removeFirst()); 179 | assertEquals("C++", list.removeFirst()); 180 | assertEquals("C", list.removeFirst()); 181 | } 182 | 183 | @Test 184 | void testRemoveLast() { 185 | // 实例化LinkedList 186 | LinkedList list = new LinkedList(); 187 | list.add("Java"); 188 | list.add("C++"); 189 | list.add("C"); 190 | 191 | // 判断存在 192 | assertEquals("C", list.removeLast()); 193 | assertEquals("C++", list.removeLast()); 194 | assertEquals("Java", list.removeLast()); 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/SequentialListStackTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * SequentialListStack Test 15 | * 16 | * @since 1.0.0 2020年5月6日 17 | * @author Way Lau 18 | */ 19 | class SequentialListStackTests { 20 | 21 | @Test 22 | void testSize() { 23 | // 实例化SequentialListStack 24 | Stack stack = new SequentialListStack( 25 | 5); 26 | assertTrue(stack.size() == 0); 27 | 28 | stack.push("Java"); 29 | assertTrue(stack.size() == 1); 30 | } 31 | 32 | @Test 33 | void testIsEmpty() { 34 | // 实例化SequentialListStack 35 | Stack stack = new SequentialListStack( 36 | 5); 37 | assertTrue(stack.isEmpty()); 38 | 39 | stack.push("Java"); 40 | assertFalse(stack.isEmpty()); 41 | } 42 | 43 | @Test 44 | void testPush() { 45 | // 实例化SequentialListStack 46 | Stack stack = new SequentialListStack( 47 | 5); 48 | stack.push(1); 49 | stack.push(2); 50 | stack.push(3); 51 | stack.push(4); 52 | stack.push(5); 53 | 54 | Throwable excpetion = assertThrows( 55 | IndexOutOfBoundsException.class, () -> { 56 | stack.push(6); // 抛异常 57 | }); 58 | 59 | assertEquals("list is full", 60 | excpetion.getMessage()); 61 | } 62 | 63 | @Test 64 | void testPop() { 65 | // 实例化SequentialListStack 66 | Stack stack = new SequentialListStack( 67 | 5); 68 | stack.push("Java"); 69 | stack.push("C++"); 70 | stack.push("C"); 71 | 72 | assertEquals("C", stack.pop()); 73 | 74 | assertTrue(stack.size() == 2); 75 | 76 | } 77 | 78 | @Test 79 | void testPeek() { 80 | // 实例化SequentialListStack 81 | Stack stack = new SequentialListStack( 82 | 5); 83 | stack.push("Java"); 84 | stack.push("C++"); 85 | stack.push("C"); 86 | 87 | assertEquals("C", stack.peek()); 88 | 89 | assertTrue(stack.size() == 3); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/SequentialListTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertNull; 9 | import static org.junit.jupiter.api.Assertions.assertThrows; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | import org.junit.jupiter.api.Test; 13 | 14 | /** 15 | * SequentialList Test 16 | * 17 | * @since 1.0.0 2020年5月3日 18 | * @author Way Lau 19 | */ 20 | class SequentialListTests { 21 | 22 | @Test 23 | void testSize() { 24 | // 实例化SequentialList 25 | List list = new SequentialList(5); 26 | assertTrue(list.size() == 0); 27 | 28 | list.add("Java"); 29 | assertTrue(list.size() == 1); 30 | } 31 | 32 | @Test 33 | void testIsEmpty() { 34 | // 实例化SequentialList 35 | List list = new SequentialList(5); 36 | assertTrue(list.isEmpty()); 37 | 38 | list.add("Java"); 39 | assertFalse(list.isEmpty()); 40 | } 41 | 42 | @Test 43 | void testContains() { 44 | // 实例化SequentialList 45 | List list = new SequentialList(5); 46 | list.add("Java"); 47 | list.add("C++"); 48 | list.add("C"); 49 | list.add("Python"); 50 | list.add("TypeScript"); 51 | 52 | // 判断存在 53 | assertTrue(list.contains("Java")); 54 | 55 | // 判断不存在 56 | assertFalse(list.contains("Java++")); 57 | } 58 | 59 | @Test 60 | void testAdd() { 61 | // 实例化SequentialList 62 | List list = new SequentialList(5); 63 | list.add(1); 64 | list.add(2); 65 | list.add(3); 66 | list.add(4); 67 | list.add(5); 68 | 69 | Throwable excpetion = assertThrows(IndexOutOfBoundsException.class, () -> { 70 | list.add(6); // 抛异常 71 | }); 72 | 73 | assertEquals("list is full", excpetion.getMessage()); 74 | } 75 | 76 | @Test 77 | void testGet() { 78 | // 实例化SequentialList 79 | List list = new SequentialList(5); 80 | list.add("Java"); 81 | list.add("C++"); 82 | list.add("C"); 83 | 84 | // 判断存在 85 | assertEquals("C++", list.get(1)); 86 | 87 | // 判断不存在 88 | assertNull(list.get(4)); 89 | } 90 | 91 | @Test 92 | void testSet() { 93 | // 实例化SequentialList 94 | List list = new SequentialList(5); 95 | list.add("Java"); 96 | list.add("C++"); 97 | list.add("C"); 98 | 99 | // 判断存在 100 | assertEquals("C", list.set(2, "Python")); 101 | 102 | // 判断不存在 103 | assertEquals(null, list.set(4, "TypeScript")); 104 | } 105 | 106 | @Test 107 | void testRemove() { 108 | // 实例化SequentialList 109 | List list = new SequentialList(5); 110 | list.add("Java"); 111 | list.add("C++"); 112 | list.add("C"); 113 | 114 | // 判断存在 115 | assertEquals("C", list.remove(2)); 116 | 117 | // 判断不存在 118 | int index = 6; 119 | Throwable excpetion = assertThrows(IndexOutOfBoundsException.class, () -> { 120 | list.remove(index); // 抛异常 121 | }); 122 | 123 | assertEquals("index " + index + " out of bounds", excpetion.getMessage()); 124 | } 125 | 126 | @Test 127 | void testAddFirst() { 128 | // 实例化SequentialList 129 | List list = new SequentialList(5); 130 | list.addFirst("Java"); 131 | list.addFirst("C++"); 132 | list.addFirst("C"); 133 | 134 | // 判断存在 135 | assertEquals("C", list.get(0)); 136 | assertEquals("C++", list.get(1)); 137 | assertEquals("Java", list.get(2)); 138 | } 139 | 140 | @Test 141 | void testAddLast() { 142 | // 实例化SequentialList 143 | List list = new SequentialList(5); 144 | list.addLast("Java"); 145 | list.addLast("C++"); 146 | list.addLast("C"); 147 | 148 | // 判断存在 149 | assertEquals("Java", list.get(0)); 150 | assertEquals("C++", list.get(1)); 151 | assertEquals("C", list.get(2)); 152 | } 153 | 154 | 155 | @Test 156 | void testRemoveFirst() { 157 | // 实例化SequentialList 158 | List list = new SequentialList(5); 159 | list.add("Java"); 160 | list.add("C++"); 161 | list.add("C"); 162 | 163 | // 判断存在 164 | assertEquals("Java", list.removeFirst()); 165 | assertEquals("C++", list.removeFirst()); 166 | assertEquals("C", list.removeFirst()); 167 | } 168 | 169 | @Test 170 | void testRemoveLast() { 171 | // 实例化SequentialList 172 | List list = new SequentialList(5); 173 | list.add("Java"); 174 | list.add("C++"); 175 | list.add("C"); 176 | 177 | // 判断存在 178 | assertEquals("C", list.removeLast()); 179 | assertEquals("C++", list.removeLast()); 180 | assertEquals("Java", list.removeLast()); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/SinglyLinkedCircularListTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * SinglyLinkedCircularList Test 15 | * 16 | * @since 1.0.0 2020年5月4日 17 | * @author Way Lau 18 | */ 19 | class SinglyLinkedCircularListTests { 20 | 21 | @Test 22 | void testSize() { 23 | // 实例化SinglyLinkedCircularList 24 | List list = new SinglyLinkedCircularList(); 25 | assertTrue(list.size() == 0); 26 | 27 | list.add("Java"); 28 | assertTrue(list.size() == 1); 29 | } 30 | 31 | @Test 32 | void testIsEmpty() { 33 | // 实例化SinglyLinkedCircularList 34 | List list = new SinglyLinkedCircularList(); 35 | assertTrue(list.isEmpty()); 36 | 37 | list.add("Java"); 38 | assertFalse(list.isEmpty()); 39 | } 40 | 41 | @Test 42 | void testContains() { 43 | // 实例化SinglyLinkedCircularList 44 | List list = new SinglyLinkedCircularList(); 45 | list.add("Java"); 46 | list.add("C++"); 47 | list.add("C"); 48 | list.add("Python"); 49 | list.add("TypeScript"); 50 | 51 | // 判断存在 52 | assertTrue(list.contains("Java")); 53 | 54 | // 判断不存在 55 | assertFalse(list.contains("Java++")); 56 | } 57 | 58 | @Test 59 | void testAdd() { 60 | // 实例化SinglyLinkedCircularList 61 | List list = new SinglyLinkedCircularList(); 62 | list.add(1); 63 | list.add(2); 64 | list.add(3); 65 | list.add(4); 66 | list.add(5); 67 | 68 | assertFalse(list.isEmpty()); 69 | } 70 | 71 | @Test 72 | void testGet() { 73 | // 实例化SinglyLinkedCircularList 74 | List list = new SinglyLinkedCircularList(); 75 | list.add("Java"); 76 | list.add("C++"); 77 | list.add("C"); 78 | 79 | // 判断存在 80 | assertEquals("C++", list.get(1)); 81 | 82 | // 判断不存在 83 | // 判断不存在 84 | int index = 6; 85 | Throwable excpetion = assertThrows( 86 | IndexOutOfBoundsException.class, () -> { 87 | list.get(index);// 抛异常 88 | }); 89 | 90 | assertEquals("index " + index + " out of bounds", 91 | excpetion.getMessage()); 92 | } 93 | 94 | @Test 95 | void testSet() { 96 | // 实例化SinglyLinkedCircularList 97 | List list = new SinglyLinkedCircularList(); 98 | list.add("Java"); 99 | list.add("C++"); 100 | list.add("C"); 101 | 102 | // 判断存在 103 | assertEquals("C", list.set(2, "Python")); 104 | 105 | // 判断不存在 106 | int index = 6; 107 | Throwable excpetion = assertThrows( 108 | IndexOutOfBoundsException.class, () -> { 109 | list.set(index, "Python");// 抛异常 110 | }); 111 | 112 | assertEquals("index " + index + " out of bounds", 113 | excpetion.getMessage()); 114 | } 115 | 116 | @Test 117 | void testRemove() { 118 | // 实例化SinglyLinkedCircularList 119 | List list = new SinglyLinkedCircularList(); 120 | list.add("Java"); 121 | list.add("C++"); 122 | list.add("C"); 123 | 124 | // 判断存在 125 | assertEquals("C", list.remove(2)); 126 | 127 | assertEquals("Java", list.get(0)); 128 | assertEquals("C++", list.get(1)); 129 | 130 | // 判断不存在 131 | int index = 6; 132 | Throwable excpetion = assertThrows( 133 | IndexOutOfBoundsException.class, () -> { 134 | list.remove(index); // 抛异常 135 | }); 136 | 137 | assertEquals("index " + index + " out of bounds", 138 | excpetion.getMessage()); 139 | } 140 | 141 | @Test 142 | void testAddFirst() { 143 | // 实例化SinglyLinkedCircularList 144 | List list = new SinglyLinkedCircularList(); 145 | list.addFirst("Java"); 146 | list.addFirst("C++"); 147 | list.addFirst("C"); 148 | 149 | // 判断存在 150 | assertEquals("C", list.get(0)); 151 | assertEquals("C++", list.get(1)); 152 | assertEquals("Java", list.get(2)); 153 | } 154 | 155 | @Test 156 | void testAddLast() { 157 | // 实例化SinglyLinkedCircularList 158 | List list = new SinglyLinkedCircularList(); 159 | list.addLast("Java"); 160 | list.addLast("C++"); 161 | list.addLast("C"); 162 | 163 | // 判断存在 164 | assertEquals("Java", list.get(0)); 165 | assertEquals("C++", list.get(1)); 166 | assertEquals("C", list.get(2)); 167 | } 168 | 169 | @Test 170 | void testRemoveFirst() { 171 | // 实例化SinglyLinkedCircularList 172 | List list = new SinglyLinkedCircularList(); 173 | list.add("Java"); 174 | list.add("C++"); 175 | list.add("C"); 176 | 177 | // 判断存在 178 | assertEquals("Java", list.removeFirst()); 179 | assertEquals("C++", list.removeFirst()); 180 | assertEquals("C", list.removeFirst()); 181 | } 182 | 183 | @Test 184 | void testRemoveLast() { 185 | // 实例化SinglyLinkedCircularList 186 | List list = new SinglyLinkedCircularList(); 187 | list.add("Java"); 188 | list.add("C++"); 189 | list.add("C"); 190 | 191 | // 判断存在 192 | assertEquals("C", list.removeLast()); 193 | assertEquals("C++", list.removeLast()); 194 | assertEquals("Java", list.removeLast()); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/SinglyLinkedListStackTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertTrue; 9 | 10 | import org.junit.jupiter.api.Test; 11 | 12 | /** 13 | * SinglyLinkedListStack Test 14 | * 15 | * @since 1.0.0 2020年5月8日 16 | * @author Way Lau 17 | */ 18 | class SinglyLinkedListStackTests { 19 | 20 | @Test 21 | void testSize() { 22 | // 实例化SinglyLinkedListStack 23 | Stack stack = new SinglyLinkedListStack(); 24 | assertTrue(stack.size() == 0); 25 | 26 | stack.push("Java"); 27 | assertTrue(stack.size() == 1); 28 | } 29 | 30 | @Test 31 | void testIsEmpty() { 32 | // 实例化SinglyLinkedListStack 33 | Stack stack = new SinglyLinkedListStack(); 34 | assertTrue(stack.isEmpty()); 35 | 36 | stack.push("Java"); 37 | assertFalse(stack.isEmpty()); 38 | } 39 | 40 | @Test 41 | void testPush() { 42 | // 实例化SinglyLinkedListStack 43 | Stack stack = new SinglyLinkedListStack(); 44 | stack.push(1); 45 | stack.push(2); 46 | stack.push(3); 47 | stack.push(4); 48 | stack.push(5); 49 | 50 | assertTrue(stack.size() == 5); 51 | } 52 | 53 | @Test 54 | void testPop() { 55 | // 实例化SinglyLinkedListStack 56 | Stack stack = new SinglyLinkedListStack(); 57 | stack.push("Java"); 58 | stack.push("C++"); 59 | stack.push("C"); 60 | 61 | assertEquals("C", stack.pop()); 62 | 63 | assertTrue(stack.size() == 2); 64 | 65 | } 66 | 67 | @Test 68 | void testPeek() { 69 | // 实例化SinglyLinkedListStack 70 | Stack stack = new SinglyLinkedListStack(); 71 | stack.push("Java"); 72 | stack.push("C++"); 73 | stack.push("C"); 74 | 75 | assertEquals("C", stack.peek()); 76 | 77 | assertTrue(stack.size() == 3); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/SinglyLinkedListTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * SinglyLinkedList Test 15 | * 16 | * @since 1.0.0 2020年5月4日 17 | * @author Way Lau 18 | */ 19 | class SinglyLinkedListTests { 20 | 21 | @Test 22 | void testSize() { 23 | // 实例化SinglyLinkedList 24 | List list = new SinglyLinkedList(); 25 | assertTrue(list.size() == 0); 26 | 27 | list.add("Java"); 28 | assertTrue(list.size() == 1); 29 | } 30 | 31 | @Test 32 | void testIsEmpty() { 33 | // 实例化SinglyLinkedList 34 | List list = new SinglyLinkedList(); 35 | assertTrue(list.isEmpty()); 36 | 37 | list.add("Java"); 38 | assertFalse(list.isEmpty()); 39 | } 40 | 41 | @Test 42 | void testContains() { 43 | // 实例化SinglyLinkedList 44 | List list = new SinglyLinkedList(); 45 | list.add("Java"); 46 | list.add("C++"); 47 | list.add("C"); 48 | list.add("Python"); 49 | list.add("TypeScript"); 50 | 51 | // 判断存在 52 | assertTrue(list.contains("Java")); 53 | 54 | // 判断不存在 55 | assertFalse(list.contains("Java++")); 56 | } 57 | 58 | @Test 59 | void testAdd() { 60 | // 实例化SinglyLinkedList 61 | List list = new SinglyLinkedList(); 62 | list.add(1); 63 | list.add(2); 64 | list.add(3); 65 | list.add(4); 66 | list.add(5); 67 | 68 | assertFalse(list.isEmpty()); 69 | } 70 | 71 | @Test 72 | void testGet() { 73 | // 实例化SinglyLinkedList 74 | List list = new SinglyLinkedList(); 75 | list.add("Java"); 76 | list.add("C++"); 77 | list.add("C"); 78 | 79 | // 判断存在 80 | assertEquals("C++", list.get(1)); 81 | 82 | // 判断不存在 83 | int index = 6; 84 | Throwable excpetion = assertThrows( 85 | IndexOutOfBoundsException.class, () -> { 86 | list.get(index);// 抛异常 87 | }); 88 | 89 | assertEquals("index " + index + " out of bounds", 90 | excpetion.getMessage()); 91 | } 92 | 93 | @Test 94 | void testSet() { 95 | // 实例化SinglyLinkedList 96 | List list = new SinglyLinkedList(); 97 | list.add("Java"); 98 | list.add("C++"); 99 | list.add("C"); 100 | 101 | // 判断存在 102 | assertEquals("C", list.set(2, "Python")); 103 | 104 | // 判断不存在 105 | int index = 6; 106 | Throwable excpetion = assertThrows( 107 | IndexOutOfBoundsException.class, () -> { 108 | list.set(index, "Python");// 抛异常 109 | }); 110 | 111 | assertEquals("index " + index + " out of bounds", 112 | excpetion.getMessage()); 113 | } 114 | 115 | @Test 116 | void testRemove() { 117 | // 实例化SinglyLinkedList 118 | List list = new SinglyLinkedList(); 119 | list.add("Java"); 120 | list.add("C++"); 121 | list.add("C"); 122 | 123 | // 判断存在 124 | assertEquals("C", list.remove(2)); 125 | 126 | assertEquals("Java", list.get(0)); 127 | assertEquals("C++", list.get(1)); 128 | 129 | // 判断不存在 130 | int index = 6; 131 | Throwable excpetion = assertThrows( 132 | IndexOutOfBoundsException.class, () -> { 133 | list.remove(index); // 抛异常 134 | }); 135 | 136 | assertEquals("index " + index + " out of bounds", 137 | excpetion.getMessage()); 138 | } 139 | 140 | @Test 141 | void testAddFirst() { 142 | // 实例化SinglyLinkedList 143 | List list = new SinglyLinkedList(); 144 | list.addFirst("Java"); 145 | list.addFirst("C++"); 146 | list.addFirst("C"); 147 | 148 | // 判断存在 149 | assertEquals("C", list.get(0)); 150 | assertEquals("C++", list.get(1)); 151 | assertEquals("Java", list.get(2)); 152 | } 153 | 154 | @Test 155 | void testAddLast() { 156 | // 实例化SinglyLinkedList 157 | List list = new SinglyLinkedList(); 158 | list.addLast("Java"); 159 | list.addLast("C++"); 160 | list.addLast("C"); 161 | 162 | // 判断存在 163 | assertEquals("Java", list.get(0)); 164 | assertEquals("C++", list.get(1)); 165 | assertEquals("C", list.get(2)); 166 | } 167 | 168 | @Test 169 | void testRemoveFirst() { 170 | // 实例化SinglyLinkedList 171 | List list = new SinglyLinkedList(); 172 | list.add("Java"); 173 | list.add("C++"); 174 | list.add("C"); 175 | 176 | // 判断存在 177 | assertEquals("Java", list.removeFirst()); 178 | assertEquals("C++", list.removeFirst()); 179 | assertEquals("C", list.removeFirst()); 180 | } 181 | 182 | @Test 183 | void testRemoveLast() { 184 | // 实例化SinglyLinkedList 185 | List list = new SinglyLinkedList(); 186 | list.add("Java"); 187 | list.add("C++"); 188 | list.add("C"); 189 | 190 | // 判断存在 191 | assertEquals("C", list.removeLast()); 192 | assertEquals("C++", list.removeLast()); 193 | assertEquals("Java", list.removeLast()); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/datastructure/VectorTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.datastructure; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | import java.util.List; 9 | import java.util.Vector; 10 | 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * ArrayList Test 15 | * 16 | * @since 1.0.0 2020年5月3日 17 | * @author Way Lau 18 | */ 19 | class VectorTests { 20 | 21 | @Test 22 | void testAdd() { 23 | // 实例化ArrayList 24 | List list = new Vector(5); 25 | list.add(1); 26 | list.add(2); 27 | list.add(3); 28 | list.add(4); 29 | list.add(5); 30 | 31 | // 触发扩容 32 | list.add(6); 33 | 34 | assertTrue(6 == list.size()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/waylau/java/demo/hannotta/HannottaTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to https://waylau.com 3 | */ 4 | package com.waylau.java.demo.hannotta; 5 | 6 | import org.junit.jupiter.api.MethodOrderer; 7 | import org.junit.jupiter.api.Order; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.TestMethodOrder; 10 | 11 | /** 12 | * Hannotta Test. 13 | * 14 | * @author Way Lau 15 | * @since 2020-11-30 16 | */ 17 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 18 | public class HannottaTest { 19 | @Order(1) 20 | @Test 21 | void testSovle() { 22 | int amountOfDisc = 3; 23 | char[] towerNames = { 'A', 'B', 'C' }; 24 | 25 | Hannotta hannotta = new Hannotta(amountOfDisc, 26 | towerNames); 27 | hannotta.solve(); 28 | } 29 | } 30 | --------------------------------------------------------------------------------