├── .gitignore ├── 07-Set-and-Map ├── 01-Set-Basics-and-BSTSet │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── BST.java │ │ ├── BSTSet.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ └── Set.java ├── 02-LinkedListSet │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── BST.java │ │ ├── BSTSet.java │ │ ├── FileOperation.java │ │ ├── LinkedList.java │ │ ├── LinkedListSet.java │ │ ├── Main.java │ │ └── Set.java ├── 03-Time-Complexity-of-Set │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── BST.java │ │ ├── BSTSet.java │ │ ├── FileOperation.java │ │ ├── LinkedList.java │ │ ├── LinkedListSet.java │ │ ├── Main.java │ │ └── Set.java ├── 04-TreeSet-and-Set-Problem-in-LeetCode │ ├── 04-TreeSet-and-Set-Problem-in-LeetCode.iml │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── Solution.java ├── 05-Map-Basics │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── Map.java ├── 06-LinkedListMap │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── FileOperation.java │ │ ├── LinkedListMap.java │ │ ├── Main.java │ │ ├── Map.java │ │ └── Solution.java ├── 07-BSTMap │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── BSTMap.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ └── Map.java ├── 08-More-about-Map │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── BSTMap.java │ │ ├── FileOperation.java │ │ ├── LinkedListMap.java │ │ ├── Main.java │ │ └── Map.java └── pom.xml ├── 08-Heap-And-Priority-Queue ├── 02-Heap-Basics │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Array.java │ │ ├── Main.java │ │ └── MaxHeap.java ├── 03-Add-And-Sift-Up-in-Heap │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Array.java │ │ ├── Main.java │ │ └── MaxHeap.java ├── 04-Extract-And-Sift-Down-in-Heap │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Array.java │ │ ├── Main.java │ │ └── MaxHeap.java ├── 05-Heapify-and-Replace-in-Heap │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Array.java │ │ ├── Main.java │ │ └── MaxHeap.java ├── 06-Priority-Queue │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Array.java │ │ ├── Main.java │ │ ├── MaxHeap.java │ │ ├── PriorityQueue.java │ │ ├── Queue.java │ │ └── Solution.java ├── 07-Priority-Queue-Problem-in-Leetcode │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── Solution.java ├── 08-Priority-Queue-in-Java │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── Solution.java ├── pom.xml └── src │ └── main │ └── java │ └── Todo.java ├── 09-Segment-Tree ├── 02-Segment-Tree-Basics │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ └── SegmentTree.java ├── 03-Building-Segment-Tree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── Merger.java │ │ └── SegmentTree.java ├── 04-Query-in-Segment-Tree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── Merger.java │ │ └── SegmentTree.java ├── 05-Problem-of-Segment-Tree-in-Leetcode │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Merger.java │ │ ├── NumArray.java │ │ ├── NumArray2.java │ │ └── SegmentTree.java ├── 06-Update-Single-In-Segment-Tree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── Merger.java │ │ ├── NumArray.java │ │ └── SegmentTree.java └── pom.xml ├── 10-Trie ├── 02-Trie-Basics │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ └── Trie.java ├── 03-Search-in-Trie │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── BST.java │ │ ├── BSTSet.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ ├── Set.java │ │ └── Trie.java ├── 04-Prefix-in-Trie │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ └── Trie.java ├── 05-Trie-and-Pattern-Match │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Dictionary.java │ │ ├── Main.java │ │ ├── Trie.java │ │ └── Trie208.java ├── 06-Trie-and-Map │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── MapSum.java └── pom.xml ├── 11-Union-Find ├── 01-What-is-Union-Find │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── UF.java ├── 02-Quick-Find │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── UF.java │ │ └── UnionFind.java ├── 03-Quick-Union │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── UF.java │ │ └── UnionFind.java ├── 04-Optimized-by-Size │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── UF.java │ │ ├── UnionFind2.java │ │ └── UnionFind3.java ├── 05-Optimized-by-Rank │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── UF.java │ │ └── UnionFind.java ├── 06-Path-Compression │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── UF.java │ │ └── UnionFind.java ├── 07-More-About-Union-Find │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ ├── UF.java │ │ └── UnionFind.java └── pom.xml ├── 12-AVL-Tree ├── 02-Calculating-Balance-Factor │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ └── Main.java ├── 03-Checking-Banlance-and-Binary-Search-Property │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ └── Main.java ├── 04-Rotation-Operations │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ └── Main.java ├── 05-The-Implementation-Left-Rotation-Right-Rotation │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ └── Main.java ├── 06-LR-and-RL │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ └── Main.java ├── 07-Remove-Elements-In-AVLTree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ └── Main.java ├── 08-Map-and-Set-In-AVL-Tree │ ├── 08-Map-and-Set-In-AVL-Tree.iml │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLMap.java │ │ ├── AVLSet.java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ ├── Map.java │ │ ├── Set.java │ │ ├── TestMapMain.java │ │ └── TestSetMain.java ├── Chapter-12-watermarked.pdf ├── README.md └── pom.xml ├── 13-Red-Black-Tree ├── 03-The-Equivalence-of-RBTree-and-2-3-Tree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ └── RBTree.java ├── 05-Keep-Root-Black-and-Left-Rotation │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ └── RBTree.java ├── 06-Flip-Color-and-Right-Rotation │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ └── RBTree.java ├── 07-Adding-in-Red-Black-Tree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ └── RBTree.java ├── 08-The-Performance-of-Red-Black-Tree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── AVLTree.java │ │ ├── BST.java │ │ ├── FileOperation.java │ │ ├── Main.java │ │ └── RBTree.java └── pom.xml ├── 14-Hash-Table ├── 01-Hash-Table-Basics │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── Solution.java ├── 03-Hash-Function-In-Java │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── Main.java │ │ └── Student.java ├── 05-HashTable-Implementation │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── FileOperation.java │ │ ├── HashTable.java │ │ └── Main.java ├── 06-Resizing-in-Hash-Table │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── FileOperation.java │ │ ├── HashTable.java │ │ └── Main.java ├── 07-More-About-in-Resizing-Hash-Table │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── FileOperation.java │ │ ├── HashTable.java │ │ └── Main.java └── pom.xml ├── 15-BTree ├── 01-The-Basic-of-BTree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── BTreeBasic.java │ │ ├── README.md │ │ └── asserts │ │ ├── 001.png │ │ ├── 002.png │ │ ├── 003.png │ │ ├── 004.png │ │ └── 005.png ├── pom.xml └── src │ └── main │ └── resources │ └── application.properties ├── 16-B+Tree ├── 01-The-Basic-of-B+Tree │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── README.md │ │ └── asserts │ │ ├── 001.png │ │ ├── 002.png │ │ ├── 003.png │ │ ├── 004.png │ │ ├── 005.png │ │ ├── 006.png │ │ ├── 007.png │ │ ├── 008.png │ │ ├── 009.png │ │ ├── 010.png │ │ ├── 011.png │ │ └── 012.png └── pom.xml └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | 3 | .idea/* 4 | *.iml 5 | -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 01-Set-Basics-and-BSTSet 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/src/main/java/BSTSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/10/31 9:58 12 | */ 13 | public class BSTSet> implements Set { 14 | 15 | private BST bst; 16 | 17 | public BSTSet() { 18 | bst = new BST<>(); 19 | } 20 | 21 | @Override 22 | public void add(E e) { 23 | bst.add(e); 24 | } 25 | 26 | @Override 27 | public boolean contains(E e) { 28 | return bst.contains(e); 29 | } 30 | 31 | @Override 32 | public void remove(E e) { 33 | bst.remove(e); 34 | } 35 | 36 | @Override 37 | public int getSize() { 38 | return bst.size(); 39 | } 40 | 41 | @Override 42 | public boolean isEmpty() { 43 | return bst.isEmpty(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.FileInputStream; 2 | import java.util.ArrayList; 3 | import java.util.Scanner; 4 | import java.util.Locale; 5 | import java.io.File; 6 | import java.io.BufferedInputStream; 7 | import java.io.IOException; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words1 = new ArrayList<>(); 10 | if(FileOperation.readFile("D:\\todo\\pride-and-prejudice.txt", words1)) { 11 | System.out.println("Total words: " + words1.size()); 12 | 13 | BSTSet set1 = new BSTSet<>(); 14 | for (String word : words1) 15 | set1.add(word); 16 | System.out.println("Total different words: " + set1.getSize()); 17 | } 18 | 19 | System.out.println(); 20 | 21 | 22 | System.out.println("A Tale of Two Cities"); 23 | 24 | ArrayList words2 = new ArrayList<>(); 25 | if(FileOperation.readFile("D:\\todo\\a-tale-of-two-cities.txt", words2)){ 26 | System.out.println("Total words: " + words2.size()); 27 | 28 | BSTSet set2 = new BSTSet<>(); 29 | for(String word: words2) 30 | set2.add(word); 31 | System.out.println("Total different words: " + set2.getSize()); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/src/main/java/Set.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/10/31 9:53 12 | */ 13 | public interface Set { 14 | 15 | void add(E e); 16 | boolean contains(E e); 17 | void remove(E e); 18 | int getSize(); 19 | boolean isEmpty(); 20 | } 21 | -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 02-LinkedListSet 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/main/java/BSTSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/10/31 9:58 12 | */ 13 | public class BSTSet> implements Set { 14 | 15 | private BST bst; 16 | 17 | public BSTSet() { 18 | bst = new BST<>(); 19 | } 20 | 21 | @Override 22 | public void add(E e) { 23 | bst.add(e); 24 | } 25 | 26 | @Override 27 | public boolean contains(E e) { 28 | return bst.contains(e); 29 | } 30 | 31 | @Override 32 | public void remove(E e) { 33 | bst.remove(e); 34 | } 35 | 36 | @Override 37 | public int getSize() { 38 | return bst.size(); 39 | } 40 | 41 | @Override 42 | public boolean isEmpty() { 43 | return bst.isEmpty(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/main/java/LinkedListSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/10/31 14:14 12 | */ 13 | public class LinkedListSet implements Set { 14 | 15 | private LinkedList list; 16 | public LinkedListSet() { 17 | list = new LinkedList<>(); 18 | } 19 | 20 | @Override 21 | public void add(E e) { 22 | if (!list.contains(e)) { 23 | list.addFirst(e); 24 | } 25 | } 26 | 27 | @Override 28 | public boolean contains(E e) { 29 | return list.contains(e); 30 | } 31 | 32 | @Override 33 | public void remove(E e) { 34 | list.removeElement(e); 35 | } 36 | 37 | @Override 38 | public int getSize() { 39 | return list.getSize(); 40 | } 41 | 42 | @Override 43 | public boolean isEmpty() { 44 | return list.isEmpty(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/10/31 14:22 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | 19 | System.out.println("Pride and Prejudice"); 20 | 21 | ArrayList words1 = new ArrayList<>(); 22 | if(FileOperation.readFile("d:\\todo\\pride-and-prejudice.txt", words1)) { 23 | System.out.println("Total words: " + words1.size()); 24 | 25 | LinkedListSet set1 = new LinkedListSet<>(); 26 | for (String word : words1) 27 | set1.add(word); 28 | System.out.println("Total different words: " + set1.getSize()); 29 | } 30 | 31 | System.out.println(); 32 | 33 | 34 | System.out.println("A Tale of Two Cities"); 35 | 36 | ArrayList words2 = new ArrayList<>(); 37 | if(FileOperation.readFile("d:\\todo\\a-tale-of-two-cities.txt", words2)){ 38 | System.out.println("Total words: " + words2.size()); 39 | 40 | LinkedListSet set2 = new LinkedListSet<>(); 41 | for(String word: words2) 42 | set2.add(word); 43 | System.out.println("Total different words: " + set2.getSize()); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/main/java/Set.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/10/31 9:53 12 | */ 13 | public interface Set { 14 | 15 | void add(E e); 16 | boolean contains(E e); 17 | void remove(E e); 18 | int getSize(); 19 | boolean isEmpty(); 20 | } 21 | -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 03-Time-Complexity-of-Set 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/main/java/BSTSet.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class BSTSet> implements Set { 4 | 5 | private BST bst; 6 | 7 | public BSTSet(){ 8 | bst = new BST<>(); 9 | } 10 | 11 | @Override 12 | public int getSize(){ 13 | return bst.size(); 14 | } 15 | 16 | @Override 17 | public boolean isEmpty(){ 18 | return bst.isEmpty(); 19 | } 20 | 21 | @Override 22 | public void add(E e){ 23 | bst.add(e); 24 | } 25 | 26 | @Override 27 | public boolean contains(E e){ 28 | return bst.contains(e); 29 | } 30 | 31 | @Override 32 | public void remove(E e){ 33 | bst.remove(e); 34 | } 35 | 36 | public static void main(String[] args) { 37 | 38 | System.out.println("Pride and Prejudice"); 39 | 40 | ArrayList words1 = new ArrayList<>(); 41 | if(FileOperation.readFile("pride-and-prejudice.txt", words1)) { 42 | System.out.println("Total words: " + words1.size()); 43 | 44 | BSTSet set1 = new BSTSet<>(); 45 | for (String word : words1) 46 | set1.add(word); 47 | System.out.println("Total different words: " + set1.getSize()); 48 | } 49 | 50 | System.out.println(); 51 | 52 | 53 | System.out.println("A Tale of Two Cities"); 54 | 55 | ArrayList words2 = new ArrayList<>(); 56 | if(FileOperation.readFile("a-tale-of-two-cities.txt", words2)){ 57 | System.out.println("Total words: " + words2.size()); 58 | 59 | BSTSet set2 = new BSTSet<>(); 60 | for(String word: words2) 61 | set2.add(word); 62 | System.out.println("Total different words: " + set2.getSize()); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/main/java/LinkedListSet.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class LinkedListSet implements Set { 4 | 5 | private LinkedList list; 6 | 7 | public LinkedListSet(){ 8 | list = new LinkedList<>(); 9 | } 10 | 11 | @Override 12 | public int getSize(){ 13 | return list.getSize(); 14 | } 15 | 16 | @Override 17 | public boolean isEmpty(){ 18 | return list.isEmpty(); 19 | } 20 | 21 | @Override 22 | public void add(E e){ 23 | if(!list.contains(e)) 24 | list.addFirst(e); 25 | } 26 | 27 | @Override 28 | public boolean contains(E e){ 29 | return list.contains(e); 30 | } 31 | 32 | @Override 33 | public void remove(E e){ 34 | list.removeElement(e); 35 | } 36 | 37 | public static void main(String[] args) { 38 | 39 | System.out.println("Pride and Prejudice"); 40 | 41 | ArrayList words1 = new ArrayList<>(); 42 | if(FileOperation.readFile("pride-and-prejudice.txt", words1)) { 43 | System.out.println("Total words: " + words1.size()); 44 | 45 | LinkedListSet set1 = new LinkedListSet<>(); 46 | for (String word : words1) 47 | set1.add(word); 48 | System.out.println("Total different words: " + set1.getSize()); 49 | } 50 | 51 | System.out.println(); 52 | 53 | 54 | System.out.println("A Tale of Two Cities"); 55 | 56 | ArrayList words2 = new ArrayList<>(); 57 | if(FileOperation.readFile("a-tale-of-two-cities.txt", words2)) { 58 | System.out.println("Total words: " + words2.size()); 59 | 60 | LinkedListSet set2 = new LinkedListSet<>(); 61 | for (String word : words2) 62 | set2.add(word); 63 | System.out.println("Total different words: " + set2.getSize()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | private static double testSet(Set set, String filename){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | System.out.println(filename); 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile(filename, words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | for (String word : words) 15 | set.add(word); 16 | System.out.println("Total different words: " + set.getSize()); 17 | } 18 | long endTime = System.nanoTime(); 19 | 20 | return (endTime - startTime) / 1000000000.0; 21 | } 22 | 23 | public static void main(String[] args) { 24 | 25 | String filename = "d:\\todo\\pride-and-prejudice.txt"; 26 | 27 | BSTSet bstSet = new BSTSet<>(); 28 | double time1 = testSet(bstSet, filename); 29 | System.out.println("BST Set: " + time1 + " s"); 30 | 31 | System.out.println(); 32 | 33 | LinkedListSet linkedListSet = new LinkedListSet<>(); 34 | double time2 = testSet(linkedListSet, filename); 35 | System.out.println("Linked List Set: " + time2 + " s"); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/main/java/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /07-Set-and-Map/04-TreeSet-and-Set-Problem-in-LeetCode/04-TreeSet-and-Set-Problem-in-LeetCode.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /07-Set-and-Map/04-TreeSet-and-Set-Problem-in-LeetCode/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 04-TreeSet-and-Set-Problem-in-LeetCode 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /07-Set-and-Map/04-TreeSet-and-Set-Problem-in-LeetCode/src/main/java/Solution.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeSet; 8 | 9 | /** 10 | * LeetCode 804号问题 11 | * 12 | * @author Leon 13 | * @version 2018/10/31 14:58 14 | */ 15 | public class Solution { 16 | 17 | public int uniqueMorseRepresentations(String[] words) { 18 | String[] codes = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."}; 19 | TreeSet set = new TreeSet<>(); 20 | for (String word : words) { 21 | StringBuilder sb = new StringBuilder(); 22 | for (int i = 0; i < word.length(); i++) { 23 | String msCode = codes[word.charAt(i) - 97]; 24 | sb.append(msCode); 25 | } 26 | set.add(String.valueOf(sb)); 27 | } 28 | return set.size(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /07-Set-and-Map/05-Map-Basics/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-Map-Basics 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /07-Set-and-Map/05-Map-Basics/src/main/java/Map.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/10/31 15:29 12 | */ 13 | public interface Map { 14 | 15 | void add(K key, V value); 16 | V get(K key); 17 | boolean contains(K key); 18 | void set(K key, V newValue); 19 | int getSize(); 20 | boolean isEmpty(); 21 | V remove(K key); 22 | } 23 | -------------------------------------------------------------------------------- /07-Set-and-Map/06-LinkedListMap/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 06-LinkedListMap 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /07-Set-and-Map/06-LinkedListMap/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /07-Set-and-Map/06-LinkedListMap/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/10/31 17:33 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args){ 18 | 19 | System.out.println("Pride and Prejudice"); 20 | 21 | ArrayList words = new ArrayList<>(); 22 | if(FileOperation.readFile("d:\\todo\\pride-and-prejudice.txt", words)) { 23 | System.out.println("Total words: " + words.size()); 24 | 25 | LinkedListMap map = new LinkedListMap<>(); 26 | for (String word : words) { 27 | if (map.contains(word)) 28 | map.set(word, map.get(word) + 1); 29 | else 30 | map.add(word, 1); 31 | } 32 | 33 | System.out.println("Total different words: " + map.getSize()); 34 | System.out.println("Frequency of PRIDE: " + map.get("pride")); 35 | System.out.println("Frequency of PREJUDICE: " + map.get("prejudice")); 36 | } 37 | 38 | System.out.println(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /07-Set-and-Map/06-LinkedListMap/src/main/java/Map.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/10/31 15:29 12 | */ 13 | public interface Map { 14 | 15 | void add(K key, V value); 16 | V get(K key); 17 | boolean contains(K key); 18 | void set(K key, V newValue); 19 | int getSize(); 20 | boolean isEmpty(); 21 | V remove(K key); 22 | } 23 | -------------------------------------------------------------------------------- /07-Set-and-Map/06-LinkedListMap/src/main/java/Solution.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | 10 | /** 11 | * 类功能描述 12 | * 13 | * @author Leon 14 | * @version 2018/10/31 17:37 15 | */ 16 | public class Solution { 17 | public int[] intersect(int[] nums1, int[] nums2) { 18 | HashMap map = new HashMap<>(); 19 | for (int num : nums1) { 20 | if (!map.containsKey(num)) { 21 | map.put(num, 1); 22 | } else { 23 | map.put(num, map.get(num) + 1); 24 | } 25 | } 26 | ArrayList list = new ArrayList<>(); 27 | for (int num : nums2) { 28 | if (map.containsKey(num)) { 29 | list.add(num); 30 | map.put(num, map.get(num) - 1); 31 | if (map.get(num) == 0) { 32 | map.remove(num); 33 | } 34 | } 35 | } 36 | 37 | int[] rs = new int[list.size()]; 38 | for (int i = 0; i < list.size(); i++) { 39 | rs[i] = list.get(i); 40 | } 41 | return rs; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /07-Set-and-Map/07-BSTMap/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 07-BSTMap 13 | 14 | 15 | -------------------------------------------------------------------------------- /07-Set-and-Map/07-BSTMap/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /07-Set-and-Map/07-BSTMap/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/4 21:31 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args){ 18 | 19 | System.out.println("Pride and Prejudice"); 20 | 21 | ArrayList words = new ArrayList<>(); 22 | if(FileOperation.readFile("d:\\todo\\pride-and-prejudice.txt", words)) { 23 | System.out.println("Total words: " + words.size()); 24 | 25 | BSTMap map = new BSTMap<>(); 26 | for (String word : words) { 27 | if (map.contains(word)) 28 | map.set(word, map.get(word) + 1); 29 | else 30 | map.add(word, 1); 31 | } 32 | 33 | System.out.println("Total different words: " + map.getSize()); 34 | System.out.println("Frequency of PRIDE: " + map.get("pride")); 35 | System.out.println("Frequency of PREJUDICE: " + map.get("prejudice")); 36 | } 37 | 38 | System.out.println(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /07-Set-and-Map/07-BSTMap/src/main/java/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | boolean contains(K key); 5 | V get(K key); 6 | void set(K key, V value); 7 | V remove(K key); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /07-Set-and-Map/08-More-about-Map/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 07-Set-and-Map 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 08-More-about-Map 13 | 14 | 15 | -------------------------------------------------------------------------------- /07-Set-and-Map/08-More-about-Map/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /07-Set-and-Map/08-More-about-Map/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | private static double testMap(Map map, String filename){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | System.out.println(filename); 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile(filename, words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | for (String word : words){ 15 | if(map.contains(word)) 16 | map.set(word, map.get(word) + 1); 17 | else 18 | map.add(word, 1); 19 | } 20 | 21 | System.out.println("Total different words: " + map.getSize()); 22 | System.out.println("Frequency of PRIDE: " + map.get("pride")); 23 | System.out.println("Frequency of PREJUDICE: " + map.get("prejudice")); 24 | } 25 | 26 | long endTime = System.nanoTime(); 27 | 28 | return (endTime - startTime) / 1000000000.0; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | String filename = "d:\\todo\\pride-and-prejudice.txt"; 34 | 35 | BSTMap bstMap = new BSTMap<>(); 36 | double time1 = testMap(bstMap, filename); 37 | System.out.println("BST Map: " + time1 + " s"); 38 | 39 | System.out.println(); 40 | 41 | LinkedListMap linkedListMap = new LinkedListMap<>(); 42 | double time2 = testMap(linkedListMap, filename); 43 | System.out.println("Linked List Map: " + time2 + " s"); 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /07-Set-and-Map/08-More-about-Map/src/main/java/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | boolean contains(K key); 5 | V get(K key); 6 | void set(K key, V newValue); 7 | V remove(K key); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /07-Set-and-Map/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.gyoomi 8 | 07-Set-and-Map 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | 13 | Data-Structures 14 | com.gyoomi 15 | 1.0-SNAPSHOT 16 | 17 | 18 | 19 | 01-Set-Basics-and-BSTSet 20 | 02-LinkedListSet 21 | 03-Time-Complexity-of-Set 22 | 04-TreeSet-and-Set-Problem-in-LeetCode 23 | 05-Map-Basics 24 | 06-LinkedListMap 25 | 07-BSTMap 26 | 08-More-about-Map 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/02-Heap-Basics/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 08-Heap-And-Priority-Queue 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 02-Heap-Basics 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/02-Heap-Basics/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/5 15:36 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | int a = 99, b = 88; 17 | a = a + b; 18 | b = a - b; 19 | a = a - b; 20 | System.out.println(a); 21 | System.out.println(b); 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/02-Heap-Basics/src/main/java/MaxHeap.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 二叉堆:最大堆 9 | * 10 | * @author Leon 11 | * @version 2018/11/5 15:37 12 | */ 13 | public class MaxHeap> { 14 | 15 | private Array data; 16 | public MaxHeap(int capacity) { 17 | data = new Array<>(capacity); 18 | } 19 | public MaxHeap() { 20 | data = new Array<>(); 21 | } 22 | 23 | public int size() { 24 | return data.getSize(); 25 | } 26 | 27 | public boolean isEmpty() { 28 | return data.isEmpty(); 29 | } 30 | 31 | /** 32 | * 返回完全二叉树的数组表示中,一个索引所表示的父亲节点的索引 33 | * 34 | * @param index 35 | * @return 36 | */ 37 | private int parent(int index) { 38 | if (index == 0) { 39 | throw new IllegalArgumentException("Index 0 does't exist parent"); 40 | } 41 | return (index - 1) / 2; 42 | } 43 | 44 | /** 45 | * 返回完全二叉树的数组表示中,一个索引所表示的左孩子的节点的索引 46 | * 47 | * @param index 48 | * @return 49 | */ 50 | private int leftChild(int index) { 51 | return index * 2 + 1; 52 | } 53 | 54 | /** 55 | * 返回完全二叉树数组表示中,一个索引所表示的右 56 | * 57 | * @param index 58 | * @return 59 | */ 60 | private int rightChild(int index) { 61 | return index * 2 + 2; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/03-Add-And-Sift-Up-in-Heap/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 08-Heap-And-Priority-Queue 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 03-Add-And-Sift-Up-in-Heap 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/03-Add-And-Sift-Up-in-Heap/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/5 15:36 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | int times = 100000; 19 | MaxHeap maxHeap = new MaxHeap<>(); 20 | for (int i = 0; i < times; i++) { 21 | maxHeap.add(new Random().nextInt(Integer.MAX_VALUE)); 22 | } 23 | System.out.println("add complete!!!"); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/03-Add-And-Sift-Up-in-Heap/src/main/java/MaxHeap.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 二叉堆:最大堆 9 | * 10 | * @author Leon 11 | * @version 2018/11/5 15:37 12 | */ 13 | public class MaxHeap> { 14 | 15 | private Array data; 16 | public MaxHeap(int capacity) { 17 | data = new Array<>(capacity); 18 | } 19 | public MaxHeap() { 20 | data = new Array<>(); 21 | } 22 | 23 | public int size() { 24 | return data.getSize(); 25 | } 26 | 27 | public boolean isEmpty() { 28 | return data.isEmpty(); 29 | } 30 | 31 | /** 32 | * 返回完全二叉树的数组表示中,一个索引所表示的父亲节点的索引 33 | * 34 | * @param index 35 | * @return 36 | */ 37 | private int parent(int index) { 38 | if (index == 0) { 39 | throw new IllegalArgumentException("Index 0 does't exist parent"); 40 | } 41 | return (index - 1) / 2; 42 | } 43 | 44 | /** 45 | * 返回完全二叉树的数组表示中,一个索引所表示的左孩子的节点的索引 46 | * 47 | * @param index 48 | * @return 49 | */ 50 | private int leftChild(int index) { 51 | return index * 2 + 1; 52 | } 53 | 54 | /** 55 | * 返回完全二叉树数组表示中,一个索引所表示的右 56 | * 57 | * @param index 58 | * @return 59 | */ 60 | private int rightChild(int index) { 61 | return index * 2 + 2; 62 | } 63 | 64 | public void add(E e) { 65 | data.addLast(e); 66 | siftUp(data.getSize() - 1); 67 | } 68 | 69 | /** 70 | * 上浮 71 | * 72 | * @param index 73 | */ 74 | private void siftUp(int index) { 75 | while (index > 0 && data.get(parent(index)).compareTo(data.get(index)) < 0) { 76 | data.swap(index, parent(index)); 77 | index = parent(index); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/04-Extract-And-Sift-Down-in-Heap/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 08-Heap-And-Priority-Queue 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 04-Extract-And-Sift-Down-in-Heap 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/04-Extract-And-Sift-Down-in-Heap/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/5 15:36 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | int n = 1000000; 19 | 20 | MaxHeap maxHeap = new MaxHeap<>(); 21 | Random random = new Random(); 22 | for(int i = 0 ; i < n ; i ++) 23 | maxHeap.add(random.nextInt(Integer.MAX_VALUE)); 24 | 25 | int[] arr = new int[n]; 26 | for(int i = 0 ; i < n ; i ++) 27 | arr[i] = maxHeap.extractMax(); 28 | 29 | for(int i = 1 ; i < n ; i ++) 30 | if(arr[i-1] < arr[i]) 31 | throw new IllegalArgumentException("Error"); 32 | 33 | System.out.println("Test MaxHeap completed."); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/05-Heapify-and-Replace-in-Heap/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 08-Heap-And-Priority-Queue 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-Heapify-and-Replace-in-Heap 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/05-Heapify-and-Replace-in-Heap/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/6 15:01 14 | */ 15 | public class Main { 16 | 17 | private static double testHeap(Integer[] testData, boolean isHeapify){ 18 | 19 | long startTime = System.nanoTime(); 20 | 21 | MaxHeap maxHeap; 22 | if(isHeapify) 23 | maxHeap = new MaxHeap<>(testData); 24 | else{ 25 | maxHeap = new MaxHeap<>(); 26 | for(int num: testData) 27 | maxHeap.add(num); 28 | } 29 | 30 | int[] arr = new int[testData.length]; 31 | for(int i = 0 ; i < testData.length ; i ++) 32 | arr[i] = maxHeap.extractMax(); 33 | 34 | for(int i = 1 ; i < testData.length ; i ++) 35 | if(arr[i-1] < arr[i]) 36 | throw new IllegalArgumentException("Error"); 37 | System.out.println("Test MaxHeap completed."); 38 | 39 | long endTime = System.nanoTime(); 40 | 41 | return (endTime - startTime) / 1000000000.0; 42 | } 43 | 44 | public static void main(String[] args) { 45 | 46 | int n = 1000000; 47 | 48 | Random random = new Random(); 49 | Integer[] testData = new Integer[n]; 50 | for(int i = 0 ; i < n ; i ++) 51 | testData[i] = random.nextInt(Integer.MAX_VALUE); 52 | 53 | double time1 = testHeap(testData, false); 54 | System.out.println("Without heapify: " + time1 + " s"); 55 | 56 | double time2 = testHeap(testData, true); 57 | System.out.println("With heapify: " + time2 + " s"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/06-Priority-Queue/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 08-Heap-And-Priority-Queue 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 06-Priority-Queue 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/06-Priority-Queue/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/6 15:22 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/06-Priority-Queue/src/main/java/PriorityQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 优先队列 9 | * 10 | * @author Leon 11 | * @version 2018/11/6 15:25 12 | */ 13 | public class PriorityQueue> implements Queue { 14 | 15 | private MaxHeap maxHeap; 16 | 17 | public PriorityQueue() { 18 | maxHeap = new MaxHeap<>(); 19 | } 20 | 21 | @Override 22 | public int getSize() { 23 | return maxHeap.size(); 24 | } 25 | 26 | @Override 27 | public boolean isEmpty() { 28 | return maxHeap.isEmpty(); 29 | } 30 | 31 | @Override 32 | public void enqueue(E e) { 33 | maxHeap.add(e); 34 | } 35 | 36 | @Override 37 | public E dequeue() { 38 | return maxHeap.extractMax(); 39 | } 40 | 41 | @Override 42 | public E getFront() { 43 | return maxHeap.findMax(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/06-Priority-Queue/src/main/java/Queue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/6 15:23 12 | */ 13 | public interface Queue { 14 | 15 | int getSize(); 16 | boolean isEmpty(); 17 | void enqueue(E e); 18 | E dequeue(); 19 | E getFront(); 20 | } 21 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/07-Priority-Queue-Problem-in-Leetcode/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 08-Heap-And-Priority-Queue 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 07-Priority-Queue-Problem-in-Leetcode 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/08-Priority-Queue-in-Java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 08-Heap-And-Priority-Queue 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 08-Priority-Queue-in-Java 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/08-Priority-Queue-in-Java/src/main/java/Solution.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | import java.util.PriorityQueue; 10 | import java.util.TreeMap; 11 | 12 | /** 13 | * 类功能描述 14 | * 15 | * @author Leon 16 | * @version 2018/11/6 17:20 17 | */ 18 | public class Solution { 19 | 20 | private class Freq implements Comparable{ 21 | 22 | public int e, freq; 23 | 24 | public Freq(int e, int freq){ 25 | this.e = e; 26 | this.freq = freq; 27 | } 28 | 29 | @Override 30 | public int compareTo(Freq another){ 31 | if (this.freq < another.freq) { 32 | return -1; 33 | } else if (this.freq > another.freq) { 34 | return 1; 35 | } else { 36 | return 0; 37 | } 38 | } 39 | } 40 | 41 | public List topKFrequent(int[] nums, int k) { 42 | 43 | TreeMap map = new TreeMap<>(); 44 | for (int num: nums){ 45 | if (map.containsKey(num)) { 46 | map.put(num, map.get(num) + 1); 47 | } else { 48 | map.put(num, 1); 49 | } 50 | } 51 | 52 | PriorityQueue pq = new PriorityQueue<>(); 53 | for (int key: map.keySet()){ 54 | if (pq.size() < k) { 55 | pq.add(new Freq(key, map.get(key))); 56 | } else if (map.get(key) > pq.peek().freq) { 57 | pq.remove(); 58 | pq.add(new Freq(key, map.get(key))); 59 | } 60 | } 61 | 62 | LinkedList rs = new LinkedList<>(); 63 | while (!pq.isEmpty()) { 64 | rs.add(pq.remove().e); 65 | } 66 | return rs; 67 | } 68 | 69 | private static void printList(List nums){ 70 | for (Integer num: nums) { 71 | System.out.print(num + " "); 72 | } 73 | System.out.println(); 74 | } 75 | 76 | public static void main(String[] args) { 77 | 78 | int[] nums = {1, 1, 1, 2, 2, 3}; 79 | int k = 2; 80 | printList((new Solution()).topKFrequent(nums, k)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 08-Heap-And-Priority-Queue 13 | pom 14 | 15 | 02-Heap-Basics 16 | 03-Add-And-Sift-Up-in-Heap 17 | 04-Extract-And-Sift-Down-in-Heap 18 | 05-Heapify-and-Replace-in-Heap 19 | 06-Priority-Queue 20 | 07-Priority-Queue-Problem-in-Leetcode 21 | 08-Priority-Queue-in-Java 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /08-Heap-And-Priority-Queue/src/main/java/Todo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/4 23:04 12 | */ 13 | public class Todo { 14 | } 15 | -------------------------------------------------------------------------------- /09-Segment-Tree/02-Segment-Tree-Basics/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 09-Segment-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 02-Segment-Tree-Basics 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /09-Segment-Tree/02-Segment-Tree-Basics/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 10:44 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /09-Segment-Tree/02-Segment-Tree-Basics/src/main/java/SegmentTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 线段树 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 10:44 12 | */ 13 | public class SegmentTree { 14 | 15 | private E[] tree; 16 | private E[] data; 17 | 18 | public SegmentTree(E[] arr) { 19 | data = (E[])new Object[arr.length]; 20 | for (int i = 0; i < arr.length; i++) { 21 | data[i] = arr[i]; 22 | } 23 | 24 | tree = (E[])new Object[4 * arr.length]; 25 | } 26 | 27 | public int getSize() { 28 | return data.length; 29 | } 30 | 31 | public E get(int index) { 32 | if (index < 0 || index >= data.length) { 33 | throw new IllegalArgumentException("Index is illegal."); 34 | } 35 | return data[index]; 36 | } 37 | 38 | /** 39 | * 返回完全二叉树数组表示中,一个索引所在元素的左孩子的索引 40 | * 41 | * @param index 42 | * @return 43 | */ 44 | public int leftChild(int index) { 45 | return index * 2 + 1; 46 | } 47 | 48 | /** 49 | * 返回完全二叉树数组表示中,一个索引所在元素的右孩子的索引 50 | * 51 | * @param index 52 | * @return 53 | */ 54 | public int rightChild(int index) { 55 | return index * 2 + 2; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /09-Segment-Tree/03-Building-Segment-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 09-Segment-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 03-Building-Segment-Tree 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /09-Segment-Tree/03-Building-Segment-Tree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 10:44 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | Integer[] nums = {-2, 0, 3, -5, 2, -1}; 17 | SegmentTree segmentTree = new SegmentTree<>(nums, (a, b) -> a + b); 18 | System.out.println(segmentTree); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /09-Segment-Tree/03-Building-Segment-Tree/src/main/java/Merger.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 11:28 12 | */ 13 | public interface Merger { 14 | 15 | E merge(E a, E b); 16 | } 17 | -------------------------------------------------------------------------------- /09-Segment-Tree/04-Query-in-Segment-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 09-Segment-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 04-Query-in-Segment-Tree 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /09-Segment-Tree/04-Query-in-Segment-Tree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 10:44 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | Integer[] nums = {-2, 0, 3, -5, 2, -1}; 17 | SegmentTree segmentTree = new SegmentTree<>(nums, (a, b) -> a + b); 18 | System.out.println(segmentTree.query(0, 2)); // 1 19 | System.out.println(segmentTree.query(0, 3)); // -4 20 | System.out.println(segmentTree.query(1, 3)); // -2 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /09-Segment-Tree/04-Query-in-Segment-Tree/src/main/java/Merger.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 11:28 12 | */ 13 | @FunctionalInterface 14 | public interface Merger { 15 | 16 | E merge(E a, E b); 17 | } 18 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Problem-of-Segment-Tree-in-Leetcode/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 09-Segment-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-Problem-of-Segment-Tree-in-Leetcode 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Problem-of-Segment-Tree-in-Leetcode/src/main/java/Merger.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 11:28 12 | */ 13 | @FunctionalInterface 14 | public interface Merger { 15 | 16 | E merge(E a, E b); 17 | } 18 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Problem-of-Segment-Tree-in-Leetcode/src/main/java/NumArray2.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * Leetcode 303 method-2 9 | * 10 | * @author Leon 11 | * @version 2018/11/8 11:39 12 | */ 13 | public class NumArray2 { 14 | private int[] sum; 15 | 16 | public NumArray2(int[] nums) { 17 | sum = new int[nums.length + 1]; 18 | sum[0] = 0; 19 | for (int i = 1; i <= nums.length; i++) { 20 | sum[i] = sum[i - 1] + nums[i - 1]; 21 | } 22 | } 23 | 24 | public int sumRange(int i, int j) { 25 | return sum[j + 1] - sum[i]; 26 | } 27 | 28 | public static void main(String[] args) { 29 | int[] nums = {1, 2, 4, 4, 1, 2}; 30 | NumArray2 na2 = new NumArray2(nums); 31 | System.out.println(na2.sumRange(2, 3)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /09-Segment-Tree/06-Update-Single-In-Segment-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 09-Segment-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 06-Update-Single-In-Segment-Tree 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /09-Segment-Tree/06-Update-Single-In-Segment-Tree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/8 10:45 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /09-Segment-Tree/06-Update-Single-In-Segment-Tree/src/main/java/Merger.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/7 11:28 12 | */ 13 | @FunctionalInterface 14 | public interface Merger { 15 | 16 | E merge(E a, E b); 17 | } 18 | -------------------------------------------------------------------------------- /09-Segment-Tree/06-Update-Single-In-Segment-Tree/src/main/java/NumArray.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/8 11:21 12 | */ 13 | public class NumArray { 14 | 15 | private SegmentTree segmentTree; 16 | 17 | public NumArray(int[] nums) { 18 | Integer[] data = new Integer[nums.length]; 19 | if (nums.length > 0) { 20 | for (int i = 0; i < nums.length; i++) { 21 | data[i] = nums[i]; 22 | } 23 | segmentTree = new SegmentTree<>(data, (a, b) -> a + b); 24 | } 25 | } 26 | 27 | public void update(int i, int val) { 28 | if (segmentTree == null) { 29 | throw new IllegalArgumentException("The segment tree is null,Must initial before using."); 30 | } 31 | segmentTree.set(i, val); 32 | } 33 | 34 | public int sumRange(int i, int j) { 35 | if (segmentTree == null) { 36 | throw new IllegalArgumentException("The segment tree is null,Must initial before using."); 37 | } 38 | return segmentTree.query(i, j); 39 | } 40 | 41 | public static void main(String[] args) { 42 | int[] nums = {1, 3, 5}; 43 | NumArray na = new NumArray(nums); 44 | System.out.println(na.sumRange(0, 2)); 45 | na.update(1, 2); 46 | System.out.println(na.sumRange(0, 2)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /09-Segment-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 09-Segment-Tree 14 | pom 15 | 1.0-SNAPSHOT 16 | 17 | 02-Segment-Tree-Basics 18 | 03-Building-Segment-Tree 19 | 04-Query-in-Segment-Tree 20 | 05-Problem-of-Segment-Tree-in-Leetcode 21 | 06-Update-Single-In-Segment-Tree 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /10-Trie/02-Trie-Basics/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10-Trie 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 02-Trie-Basics 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /10-Trie/02-Trie-Basics/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/8 15:36 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /10-Trie/02-Trie-Basics/src/main/java/Trie.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * 字典树 11 | * 12 | * @author Leon 13 | * @version 2018/11/8 15:36 14 | */ 15 | public class Trie { 16 | 17 | private Node root; 18 | private int size; 19 | 20 | public Trie() { 21 | root = new Node(); 22 | size = 0; 23 | } 24 | 25 | public int getSize() { 26 | return size; 27 | } 28 | 29 | public void add(String word) { 30 | Node cur = root; 31 | for (int i = 0; i < word.length(); i++) { 32 | char c = word.charAt(i); 33 | if (cur.next.get(c) == null) { 34 | cur.next.put(c, new Node()); 35 | } 36 | cur = cur.next.get(c); 37 | } 38 | if (!cur.isWord) { 39 | cur.isWord = true; 40 | size++; 41 | } 42 | } 43 | 44 | private class Node { 45 | public boolean isWord; 46 | public TreeMap next; 47 | public Node(boolean isWord) { 48 | this.isWord = isWord; 49 | next = new TreeMap<>(); 50 | } 51 | public Node() { 52 | this(false); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /10-Trie/03-Search-in-Trie/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10-Trie 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 03-Search-in-Trie 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /10-Trie/03-Search-in-Trie/src/main/java/BSTSet.java: -------------------------------------------------------------------------------- 1 | public class BSTSet> implements Set { 2 | 3 | private BST bst; 4 | 5 | public BSTSet(){ 6 | bst = new BST<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return bst.size(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return bst.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void add(E e){ 21 | bst.add(e); 22 | } 23 | 24 | @Override 25 | public boolean contains(E e){ 26 | return bst.contains(e); 27 | } 28 | 29 | @Override 30 | public void remove(E e){ 31 | bst.remove(e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /10-Trie/03-Search-in-Trie/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /10-Trie/03-Search-in-Trie/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/8 15:36 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | System.out.println("Pride and Prejudice"); 19 | 20 | ArrayList words = new ArrayList<>(); 21 | if(FileOperation.readFile("d:\\todo\\a-tale-of-two-cities.txt", words)) { 22 | 23 | long startTime = System.nanoTime(); 24 | 25 | BSTSet set = new BSTSet<>(); 26 | for (String word : words) 27 | set.add(word); 28 | 29 | for (String word : words) 30 | set.contains(word); 31 | 32 | long endTime = System.nanoTime(); 33 | 34 | double time = (endTime - startTime) / 1000000000.0; 35 | 36 | System.out.println("Total different words: " + set.getSize()); 37 | System.out.println("BSTSet: " + time + " s"); 38 | 39 | // --- 40 | 41 | startTime = System.nanoTime(); 42 | 43 | Trie trie = new Trie(); 44 | for (String word : words) 45 | trie.add(word); 46 | 47 | for (String word : words) 48 | trie.contains(word); 49 | 50 | endTime = System.nanoTime(); 51 | 52 | time = (endTime - startTime) / 1000000000.0; 53 | 54 | System.out.println("Total different words: " + trie.getSize()); 55 | System.out.println("Trie: " + time + " s"); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /10-Trie/03-Search-in-Trie/src/main/java/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /10-Trie/03-Search-in-Trie/src/main/java/Trie.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * 字典树 11 | * 12 | * @author Leon 13 | * @version 2018/11/8 15:36 14 | */ 15 | public class Trie { 16 | 17 | private Node root; 18 | private int size; 19 | 20 | public Trie() { 21 | root = new Node(); 22 | size = 0; 23 | } 24 | 25 | public int getSize() { 26 | return size; 27 | } 28 | 29 | public void add(String word) { 30 | Node cur = root; 31 | for (int i = 0; i < word.length(); i++) { 32 | char c = word.charAt(i); 33 | if (cur.next.get(c) == null) { 34 | cur.next.put(c, new Node()); 35 | } 36 | cur = cur.next.get(c); 37 | } 38 | if (!cur.isWord) { 39 | cur.isWord = true; 40 | size++; 41 | } 42 | } 43 | 44 | public boolean contains(String word) { 45 | Node cur = root; 46 | for (int i = 0; i < word.length(); i++) { 47 | char c = word.charAt(i); 48 | if (cur.next.get(c) == null) { 49 | return false; 50 | } 51 | cur = cur.next.get(c); 52 | } 53 | return cur.isWord; 54 | } 55 | 56 | private class Node { 57 | public boolean isWord; 58 | public TreeMap next; 59 | public Node(boolean isWord) { 60 | this.isWord = isWord; 61 | next = new TreeMap<>(); 62 | } 63 | public Node() { 64 | this(false); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /10-Trie/04-Prefix-in-Trie/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10-Trie 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 04-Prefix-in-Trie 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /10-Trie/04-Prefix-in-Trie/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/8 15:36 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | Trie trie = new Trie(); 17 | trie.add("hello"); 18 | trie.add("hi"); 19 | trie.add("pan"); 20 | trie.add("panda"); 21 | trie.add("door"); 22 | trie.add("deer"); 23 | System.out.println(trie.startsWith("pal")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /10-Trie/04-Prefix-in-Trie/src/main/java/Trie.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * 字典树 11 | * 12 | * @author Leon 13 | * @version 2018/11/8 15:36 14 | */ 15 | public class Trie { 16 | 17 | private Node root; 18 | private int size; 19 | 20 | public Trie() { 21 | root = new Node(); 22 | size = 0; 23 | } 24 | 25 | public int getSize() { 26 | return size; 27 | } 28 | 29 | public void add(String word) { 30 | Node cur = root; 31 | for (int i = 0; i < word.length(); i++) { 32 | char c = word.charAt(i); 33 | if (cur.next.get(c) == null) { 34 | cur.next.put(c, new Node()); 35 | } 36 | cur = cur.next.get(c); 37 | } 38 | if (!cur.isWord) { 39 | cur.isWord = true; 40 | size++; 41 | } 42 | } 43 | 44 | public boolean contains(String word) { 45 | Node cur = root; 46 | for (int i = 0; i < word.length(); i++) { 47 | char c = word.charAt(i); 48 | if (cur.next.get(c) == null) { 49 | return false; 50 | } 51 | cur = cur.next.get(c); 52 | } 53 | return cur.isWord; 54 | } 55 | 56 | public boolean startsWith(String prefix) { 57 | Node cur = root; 58 | for (int i = 0; i < prefix.length(); i++) { 59 | char c = prefix.charAt(i); 60 | if (cur.next.get(c) == null) { 61 | return false; 62 | } 63 | cur = cur.next.get(c); 64 | } 65 | return true; 66 | } 67 | 68 | private class Node { 69 | public boolean isWord; 70 | public TreeMap next; 71 | public Node(boolean isWord) { 72 | this.isWord = isWord; 73 | next = new TreeMap<>(); 74 | } 75 | public Node() { 76 | this(false); 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /10-Trie/05-Trie-and-Pattern-Match/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10-Trie 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-Trie-and-Pattern-Match 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /10-Trie/05-Trie-and-Pattern-Match/src/main/java/Dictionary.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/9 10:58 14 | */ 15 | public class Dictionary { 16 | 17 | private Node root; 18 | public Dictionary() { 19 | root = new Node(); 20 | } 21 | 22 | public void addWord(String word) { 23 | Node cur = root; 24 | for (int i = 0; i < word.length(); i++) { 25 | char c = word.charAt(i); 26 | if (cur.next.get(c) == null) { 27 | cur.next.put(c, new Node()); 28 | } 29 | cur = cur.next.get(c); 30 | } 31 | if (!cur.isWord) { 32 | cur.isWord = true; 33 | } 34 | } 35 | 36 | public boolean search(String word) { 37 | if (word == null || word.length() < 1) { 38 | return false; 39 | } 40 | return match(root, word, 0); 41 | } 42 | 43 | private boolean match(Node node, String word, int index) { 44 | if (index == word.length()) { 45 | return node.isWord; 46 | } 47 | char c = word.charAt(index); 48 | if (c != '.') { 49 | if (node.next.get(c) == null) { 50 | return false; 51 | } 52 | return match(node.next.get(c), word, index + 1); 53 | } else { 54 | for (char nextChar : node.next.keySet()) { 55 | if (match(node.next.get(nextChar), word, index + 1)) { 56 | return true; 57 | } 58 | } 59 | return false; 60 | } 61 | } 62 | 63 | private class Node { 64 | public boolean isWord; 65 | public TreeMap next; 66 | public Node (boolean isWord) { 67 | this.isWord = isWord; 68 | next = new TreeMap<>(); 69 | } 70 | public Node() { 71 | this(false); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /10-Trie/05-Trie-and-Pattern-Match/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 14:48 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | Dictionary dic = new Dictionary(); 17 | dic.addWord("WordDictionary"); 18 | dic.addWord("addWord"); 19 | dic.addWord("addWord"); 20 | dic.addWord("addWord"); 21 | dic.addWord("search"); 22 | dic.addWord("search"); 23 | dic.addWord("search"); 24 | dic.addWord("search"); 25 | System.out.println(dic.search("")); 26 | System.out.println(dic.search("bad")); 27 | System.out.println(dic.search(".ad")); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /10-Trie/05-Trie-and-Pattern-Match/src/main/java/Trie.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * 字典树 11 | * 12 | * @author Leon 13 | * @version 2018/11/8 15:36 14 | */ 15 | public class Trie { 16 | 17 | private Node root; 18 | private int size; 19 | 20 | public Trie() { 21 | root = new Node(); 22 | size = 0; 23 | } 24 | 25 | public int getSize() { 26 | return size; 27 | } 28 | 29 | public void add(String word) { 30 | Node cur = root; 31 | for (int i = 0; i < word.length(); i++) { 32 | char c = word.charAt(i); 33 | if (cur.next.get(c) == null) { 34 | cur.next.put(c, new Node()); 35 | } 36 | cur = cur.next.get(c); 37 | } 38 | if (!cur.isWord) { 39 | cur.isWord = true; 40 | size++; 41 | } 42 | } 43 | 44 | public boolean contains(String word) { 45 | Node cur = root; 46 | for (int i = 0; i < word.length(); i++) { 47 | char c = word.charAt(i); 48 | if (cur.next.get(c) == null) { 49 | return false; 50 | } 51 | cur = cur.next.get(c); 52 | } 53 | return cur.isWord; 54 | } 55 | 56 | public boolean startsWith(String prefix) { 57 | Node cur = root; 58 | for (int i = 0; i < prefix.length(); i++) { 59 | char c = prefix.charAt(i); 60 | if (cur.next.get(c) == null) { 61 | return false; 62 | } 63 | cur = cur.next.get(c); 64 | } 65 | return true; 66 | } 67 | 68 | private class Node { 69 | public boolean isWord; 70 | public TreeMap next; 71 | public Node(boolean isWord) { 72 | this.isWord = isWord; 73 | next = new TreeMap<>(); 74 | } 75 | public Node() { 76 | this(false); 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /10-Trie/05-Trie-and-Pattern-Match/src/main/java/Trie208.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * Leetcode-208 11 | * 12 | * @author Leon 13 | * @version 2018/11/9 10:34 14 | */ 15 | public class Trie208 { 16 | 17 | 18 | private Node root; 19 | private int size; 20 | 21 | public Trie208() { 22 | root = new Node(); 23 | size = 0; 24 | } 25 | 26 | public int getSize() { 27 | return size; 28 | } 29 | 30 | public void insert(String word) { 31 | Node cur = root; 32 | for (int i = 0; i < word.length(); i++) { 33 | char c = word.charAt(i); 34 | if (cur.next.get(c) == null) { 35 | cur.next.put(c, new Node()); 36 | } 37 | cur = cur.next.get(c); 38 | } 39 | if (!cur.isWord) { 40 | cur.isWord = true; 41 | size++; 42 | } 43 | } 44 | 45 | public boolean search(String word) { 46 | Node cur = root; 47 | for (int i = 0; i < word.length(); i++) { 48 | char c = word.charAt(i); 49 | if (cur.next.get(c) == null) { 50 | return false; 51 | } 52 | cur = cur.next.get(c); 53 | } 54 | return cur.isWord; 55 | } 56 | 57 | public boolean startsWith(String prefix) { 58 | Node cur = root; 59 | for (int i = 0; i < prefix.length(); i++) { 60 | char c = prefix.charAt(i); 61 | if (cur.next.get(c) == null) { 62 | return false; 63 | } 64 | cur = cur.next.get(c); 65 | } 66 | return true; 67 | } 68 | 69 | private class Node { 70 | public boolean isWord; 71 | public TreeMap next; 72 | public Node(boolean isWord) { 73 | this.isWord = isWord; 74 | next = new TreeMap<>(); 75 | } 76 | public Node() { 77 | this(false); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /10-Trie/06-Trie-and-Map/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10-Trie 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 06-Trie-and-Map 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /10-Trie/06-Trie-and-Map/src/main/java/MapSum.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/9 15:16 14 | */ 15 | public class MapSum { 16 | 17 | private Node root; 18 | 19 | public MapSum() { 20 | root = new Node(); 21 | } 22 | 23 | public void insert(String key, int val) { 24 | Node cur = root; 25 | for (int i = 0; i < key.length(); i++) { 26 | char c = key.charAt(i); 27 | if (cur.next.get(c) == null) { 28 | cur.next.put(c, new Node()); 29 | } 30 | cur = cur.next.get(c); 31 | } 32 | cur.value = val; 33 | } 34 | 35 | public int sum(String prefix) { 36 | Node cur = root; 37 | for (int i = 0; i < prefix.length(); i++) { 38 | char c = prefix.charAt(i); 39 | if (cur.next.get(c) == null) { 40 | return 0; 41 | } 42 | cur = cur.next.get(c); 43 | } 44 | return sum(cur); 45 | } 46 | 47 | private int sum(Node node) { 48 | int res = node.value; 49 | for (char c :node.next.keySet()){ 50 | res += sum(node.next.get(c)); 51 | } 52 | return res; 53 | } 54 | 55 | 56 | 57 | private class Node { 58 | public int value; 59 | public TreeMap next; 60 | public Node(int value) { 61 | this.value = value; 62 | } 63 | public Node() { 64 | this(0); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /10-Trie/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 10-Trie 14 | pom 15 | 1.0-SNAPSHOT 16 | 17 | 02-Trie-Basics 18 | 03-Search-in-Trie 19 | 04-Prefix-in-Trie 20 | 05-Trie-and-Pattern-Match 21 | 06-Trie-and-Map 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /11-Union-Find/01-What-is-Union-Find/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11-Union-Find 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 01-What-is-Union-Find 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /11-Union-Find/01-What-is-Union-Find/src/main/java/UF.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 并查集 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 15:56 12 | */ 13 | public interface UF { 14 | 15 | int getSize(); 16 | boolean isConnected(int p, int q); 17 | void unionElements(int p, int q); 18 | } 19 | -------------------------------------------------------------------------------- /11-Union-Find/02-Quick-Find/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11-Union-Find 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 02-Quick-Find 13 | 14 | 15 | -------------------------------------------------------------------------------- /11-Union-Find/02-Quick-Find/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/10 18:31 14 | */ 15 | public class Main { 16 | 17 | private static double testUF(UF uf, int m){ 18 | 19 | int size = uf.getSize(); 20 | Random random = new Random(); 21 | 22 | long startTime = System.nanoTime(); 23 | 24 | 25 | for(int i = 0 ; i < m ; i ++){ 26 | int a = random.nextInt(size); 27 | int b = random.nextInt(size); 28 | uf.unionElements(a, b); 29 | } 30 | 31 | for(int i = 0 ; i < m ; i ++){ 32 | int a = random.nextInt(size); 33 | int b = random.nextInt(size); 34 | uf.isConnected(a, b); 35 | } 36 | 37 | long endTime = System.nanoTime(); 38 | 39 | double time = (endTime - startTime) / 1000000000.0; 40 | return time; 41 | } 42 | 43 | public static void main(String[] args) { 44 | 45 | int size = 10; 46 | int m = 9; 47 | UnionFind uf = new UnionFind(size); 48 | System.out.println(testUF(uf, m) + " s"); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /11-Union-Find/02-Quick-Find/src/main/java/UF.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 15:56 12 | */ 13 | public interface UF { 14 | 15 | int getSize(); 16 | boolean isConnected(int p, int q); 17 | void unionElements(int p, int q); 18 | } 19 | -------------------------------------------------------------------------------- /11-Union-Find/02-Quick-Find/src/main/java/UnionFind.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/10 17:51 12 | */ 13 | public class UnionFind implements UF { 14 | 15 | private int[] id; 16 | 17 | public UnionFind(int size) { 18 | id = new int[size]; 19 | for (int i = 0; i < size; i++) { 20 | id[i] = i; 21 | } 22 | } 23 | 24 | @Override 25 | public int getSize() { 26 | return id.length; 27 | } 28 | 29 | /** 30 | * 查看元素p和元素q是否所属一个集合 31 | * 时空复杂度:O(1) 32 | * 33 | * @param p 34 | * @param q 35 | * @return 36 | */ 37 | @Override 38 | public boolean isConnected(int p, int q) { 39 | return find(p) == find(q); 40 | } 41 | 42 | /** 43 | * 查找元素p对应的集合id 44 | * 时空复杂度:O(1) 45 | * 46 | * @param p 47 | * @return 48 | */ 49 | private int find(int p) { 50 | if (p < 0 || p >= id.length) { 51 | throw new IllegalArgumentException("p is out of bound."); 52 | } 53 | return id[p]; 54 | } 55 | 56 | /** 57 | * 合并元素p和元素q所属的集合 58 | * O(n) 复杂度 59 | * 60 | * @param p 61 | * @param q 62 | */ 63 | @Override 64 | public void unionElements(int p, int q) { 65 | int pId = find(p); 66 | int qId = find(q); 67 | if (pId == qId) { 68 | return; 69 | } 70 | // 合并过程需要遍历所有的元素,将两个元素的所属的集合编号合并 71 | for (int i = 0; i < id.length; i++) { 72 | if (id[i] == pId) { 73 | id[i] = qId; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11-Union-Find 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 03-Quick-Union 13 | 14 | 15 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/10 20:26 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | UnionFind uf = new UnionFind(10); 17 | uf.unionElements(1, 2); 18 | uf.unionElements(2, 8); 19 | uf.unionElements(2, 5); 20 | System.out.println(uf); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/src/main/java/UF.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 15:56 12 | */ 13 | public interface UF { 14 | 15 | int getSize(); 16 | boolean isConnected(int p, int q); 17 | void unionElements(int p, int q); 18 | } 19 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/src/main/java/UnionFind.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/10 17:51 12 | */ 13 | public class UnionFind implements UF { 14 | 15 | private int[] parent; 16 | 17 | public UnionFind(int size) { 18 | parent = new int[size]; 19 | for (int i = 0; i < size; i++) { 20 | parent[i] = i; 21 | } 22 | } 23 | 24 | @Override 25 | public int getSize() { 26 | return parent.length; 27 | } 28 | 29 | /** 30 | * 查看元素p和元素q是否所属一个集合 31 | * 时空复杂度:O(1) 32 | * 33 | * @param p 34 | * @param q 35 | * @return 36 | */ 37 | @Override 38 | public boolean isConnected(int p, int q) { 39 | return find(p) == find(q); 40 | } 41 | 42 | /** 43 | * 查找过程:查找p元素对应的集合编号 44 | * O(h) h为树的高度 45 | * 46 | * 47 | * @param p 48 | * @return 49 | */ 50 | private int find(int p) { 51 | if (p < 0 || p >= parent.length) { 52 | throw new IllegalArgumentException("p is out of bound."); 53 | } 54 | // 不断向上查找父亲节点,直到找到根节点 55 | // 父节点的特性:p == parent[p] 56 | while (p != parent[p]) { 57 | p = parent[p]; 58 | } 59 | return p; 60 | } 61 | 62 | /** 63 | * 合并元素p和元素q所属的集合 64 | * O(n) 复杂度 65 | * 66 | * @param p 67 | * @param q 68 | */ 69 | @Override 70 | public void unionElements(int p, int q) { 71 | int pRoot = find(p); 72 | int qRoot = find(q); 73 | if (pRoot == qRoot) { 74 | return; 75 | } 76 | parent[pRoot] = qRoot; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11-Union-Find 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 04-Optimized-by-Size 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/10 20:26 14 | */ 15 | public class Main { 16 | 17 | private static double testUF(UF uf, int m){ 18 | 19 | int size = uf.getSize(); 20 | Random random = new Random(); 21 | 22 | long startTime = System.nanoTime(); 23 | 24 | 25 | for(int i = 0 ; i < m ; i ++){ 26 | int a = random.nextInt(size); 27 | int b = random.nextInt(size); 28 | uf.unionElements(a, b); 29 | } 30 | 31 | for(int i = 0 ; i < m ; i ++){ 32 | int a = random.nextInt(size); 33 | int b = random.nextInt(size); 34 | uf.isConnected(a, b); 35 | } 36 | 37 | long endTime = System.nanoTime(); 38 | 39 | return (endTime - startTime) / 1000000000.0; 40 | } 41 | 42 | public static void main(String[] args) { 43 | 44 | // UnionFind1 慢于 UnionFind3 45 | // int size = 100000; 46 | // int m = 10000; 47 | 48 | // UnionFind3 慢于 UnionFind1, 但UnionFind3最快 49 | int size = 100000; 50 | int m = 10000; 51 | 52 | UnionFind3 uf = new UnionFind3(size); 53 | System.out.println("UnionFind3 : " + testUF(uf, m) + " s"); 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/main/java/UF.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 15:56 12 | */ 13 | public interface UF { 14 | 15 | int getSize(); 16 | boolean isConnected(int p, int q); 17 | void unionElements(int p, int q); 18 | } 19 | -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/main/java/UnionFind2.java: -------------------------------------------------------------------------------- 1 | // 我们的第二版Union-Find 2 | public class UnionFind2 implements UF { 3 | 4 | // 我们的第二版Union-Find, 使用一个数组构建一棵指向父节点的树 5 | // parent[i]表示第一个元素所指向的父节点 6 | private int[] parent; 7 | 8 | // 构造函数 9 | public UnionFind2(int size){ 10 | 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ) 15 | parent[i] = i; 16 | } 17 | 18 | @Override 19 | public int getSize(){ 20 | return parent.length; 21 | } 22 | 23 | // 查找过程, 查找元素p所对应的集合编号 24 | // O(h)复杂度, h为树的高度 25 | private int find(int p){ 26 | if(p < 0 || p >= parent.length) 27 | throw new IllegalArgumentException("p is out of bound."); 28 | 29 | // 不断去查询自己的父亲节点, 直到到达根节点 30 | // 根节点的特点: parent[p] == p 31 | while(p != parent[p]) 32 | p = parent[p]; 33 | return p; 34 | } 35 | 36 | // 查看元素p和元素q是否所属一个集合 37 | // O(h)复杂度, h为树的高度 38 | @Override 39 | public boolean isConnected( int p , int q ){ 40 | return find(p) == find(q); 41 | } 42 | 43 | // 合并元素p和元素q所属的集合 44 | // O(h)复杂度, h为树的高度 45 | @Override 46 | public void unionElements(int p, int q){ 47 | 48 | int pRoot = find(p); 49 | int qRoot = find(q); 50 | 51 | if( pRoot == qRoot ) 52 | return; 53 | 54 | parent[pRoot] = qRoot; 55 | } 56 | } -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/main/java/UnionFind3.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/10 17:51 12 | */ 13 | public class UnionFind3 implements UF { 14 | 15 | private int[] parent; // parent[i]表示,第i个元素所指向的父节点 16 | private int[] sz; // sz[i]表示,以i为根的元素的个数 17 | 18 | public UnionFind3(int size) { 19 | parent = new int[size]; 20 | sz = new int[size]; 21 | // 初始化时,每个parent[i]指向自己。表示每个元素自己成一个集合。 22 | for (int i = 0; i < size; i++) { 23 | parent[i] = i; 24 | sz[i] = 1; 25 | } 26 | } 27 | 28 | @Override 29 | public int getSize() { 30 | return parent.length; 31 | } 32 | 33 | /** 34 | * 查看元素p和元素q是否所属一个集合 35 | * 时空复杂度:O(1) 36 | * 37 | * @param p 38 | * @param q 39 | * @return 40 | */ 41 | @Override 42 | public boolean isConnected(int p, int q) { 43 | return find(p) == find(q); 44 | } 45 | 46 | /** 47 | * 查找过程:查找p元素对应的集合编号 48 | * O(h) h为树的高度 49 | * 50 | * 51 | * @param p 52 | * @return 53 | */ 54 | private int find(int p) { 55 | if (p < 0 || p >= parent.length) { 56 | throw new IllegalArgumentException("p is out of bound."); 57 | } 58 | // 不断向上查找父亲节点,直到找到根节点 59 | // 父节点的特性:p == parent[p] 60 | while (p != parent[p]) { 61 | p = parent[p]; 62 | } 63 | return p; 64 | } 65 | 66 | /** 67 | * 合并元素p和元素q所属的集合 68 | * O(n) 复杂度 69 | * 70 | * @param p 71 | * @param q 72 | */ 73 | @Override 74 | public void unionElements(int p, int q) { 75 | int pRoot = find(p); 76 | int qRoot = find(q); 77 | if (pRoot == qRoot) { 78 | return; 79 | } 80 | // 根据需要合并的两个不同的树的数量,来判断合并的方向 81 | // 将元素个数少的集合合并到元素个数多的集合上 82 | if (sz[pRoot] <= sz[qRoot]) { 83 | parent[pRoot] = qRoot; 84 | sz[qRoot] += sz[pRoot]; 85 | } else { // sz[pRoot] <= sz[qRoot] 86 | parent[qRoot] = pRoot; 87 | sz[pRoot] = sz[qRoot]; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11-Union-Find 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-Optimized-by-Rank 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/12 11:31 14 | */ 15 | public class Main { 16 | 17 | private static double testUF(UF uf, int m){ 18 | 19 | int size = uf.getSize(); 20 | Random random = new Random(); 21 | 22 | long startTime = System.nanoTime(); 23 | 24 | 25 | for(int i = 0 ; i < m ; i ++){ 26 | int a = random.nextInt(size); 27 | int b = random.nextInt(size); 28 | uf.unionElements(a, b); 29 | } 30 | 31 | for(int i = 0 ; i < m ; i ++){ 32 | int a = random.nextInt(size); 33 | int b = random.nextInt(size); 34 | uf.isConnected(a, b); 35 | } 36 | 37 | long endTime = System.nanoTime(); 38 | 39 | return (endTime - startTime) / 1000000000.0; 40 | } 41 | 42 | public static void main(String[] args) { 43 | int size = 100000; 44 | int m = 10000000; 45 | 46 | UnionFind uf = new UnionFind(size); 47 | System.out.println("UnionFind : " + testUF(uf, m) + " s"); 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/main/java/UF.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 15:56 12 | */ 13 | public interface UF { 14 | 15 | int getSize(); 16 | boolean isConnected(int p, int q); 17 | void unionElements(int p, int q); 18 | } 19 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/main/java/UnionFind.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/10 17:51 12 | */ 13 | public class UnionFind implements UF { 14 | 15 | private int[] parent; // parent[i]表示,第i个元素所指向的父节点 16 | private int[] rank; // rank[i]表示,以第i个元素为根的树的层数 17 | 18 | public UnionFind(int size) { 19 | parent = new int[size]; 20 | rank = new int[size]; 21 | // 初始化时,每个parent[i]指向自己。表示每个元素自己成一个集合。 22 | for (int i = 0; i < size; i++) { 23 | parent[i] = i; 24 | rank[i] = 1; 25 | } 26 | } 27 | 28 | @Override 29 | public int getSize() { 30 | return parent.length; 31 | } 32 | 33 | /** 34 | * 查看元素p和元素q是否所属一个集合 35 | * 时空复杂度:O(1) 36 | * 37 | * @param p 38 | * @param q 39 | * @return 40 | */ 41 | @Override 42 | public boolean isConnected(int p, int q) { 43 | return find(p) == find(q); 44 | } 45 | 46 | /** 47 | * 查找过程:查找p元素对应的集合编号 48 | * O(h) h为树的高度 49 | * 50 | * 51 | * @param p 52 | * @return 53 | */ 54 | private int find(int p) { 55 | if (p < 0 || p >= parent.length) { 56 | throw new IllegalArgumentException("p is out of bound."); 57 | } 58 | // 不断向上查找父亲节点,直到找到根节点 59 | // 父节点的特性:p == parent[p] 60 | while (p != parent[p]) { 61 | p = parent[p]; 62 | } 63 | return p; 64 | } 65 | 66 | /** 67 | * 合并元素p和元素q所属的集合 68 | * O(n) 复杂度 69 | * 70 | * @param p 71 | * @param q 72 | */ 73 | @Override 74 | public void unionElements(int p, int q) { 75 | int pRoot = find(p); 76 | int qRoot = find(q); 77 | if (pRoot == qRoot) { 78 | return; 79 | } 80 | // 根据需要合并的两个不同的树的数量,来判断合并的方向 81 | // 将元素层数少的集合合并到元素层数多的集合上 82 | if (rank[pRoot] < rank[qRoot]) { 83 | parent[pRoot] = qRoot; 84 | } else if (rank[pRoot] > rank[qRoot]) { // sz[pRoot] <= sz[qRoot] 85 | parent[qRoot] = pRoot; 86 | } else { // rank[pRoot] == rank[qRoot] 87 | parent[pRoot] = qRoot; 88 | rank[qRoot] += 1; // 此时,被指向的节点的层数加1 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11-Union-Find 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 06-Path-Compression 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/12 11:31 14 | */ 15 | public class Main { 16 | 17 | private static double testUF(UF uf, int m){ 18 | 19 | int size = uf.getSize(); 20 | Random random = new Random(); 21 | 22 | long startTime = System.nanoTime(); 23 | 24 | 25 | for(int i = 0 ; i < m ; i ++){ 26 | int a = random.nextInt(size); 27 | int b = random.nextInt(size); 28 | uf.unionElements(a, b); 29 | } 30 | 31 | for(int i = 0 ; i < m ; i ++){ 32 | int a = random.nextInt(size); 33 | int b = random.nextInt(size); 34 | uf.isConnected(a, b); 35 | } 36 | 37 | long endTime = System.nanoTime(); 38 | 39 | return (endTime - startTime) / 1000000000.0; 40 | } 41 | 42 | public static void main(String[] args) { 43 | int size = 100000; 44 | int m = 1000000000; 45 | 46 | UnionFind uf = new UnionFind(size); 47 | System.out.println("UnionFind : " + testUF(uf, m) + " s"); 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/main/java/UF.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 15:56 12 | */ 13 | public interface UF { 14 | 15 | int getSize(); 16 | boolean isConnected(int p, int q); 17 | void unionElements(int p, int q); 18 | } 19 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-About-Union-Find/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11-Union-Find 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 07-More-About-Union-Find 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-About-Union-Find/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/11/12 11:31 14 | */ 15 | public class Main { 16 | 17 | private static double testUF(UF uf, int m){ 18 | 19 | int size = uf.getSize(); 20 | Random random = new Random(); 21 | 22 | long startTime = System.nanoTime(); 23 | 24 | 25 | for(int i = 0 ; i < m ; i ++){ 26 | int a = random.nextInt(size); 27 | int b = random.nextInt(size); 28 | uf.unionElements(a, b); 29 | } 30 | 31 | for(int i = 0 ; i < m ; i ++){ 32 | int a = random.nextInt(size); 33 | int b = random.nextInt(size); 34 | uf.isConnected(a, b); 35 | } 36 | 37 | long endTime = System.nanoTime(); 38 | 39 | return (endTime - startTime) / 1000000000.0; 40 | } 41 | 42 | public static void main(String[] args) { 43 | int size = 100000; 44 | int m = 1000000000; 45 | 46 | UnionFind uf = new UnionFind(size); 47 | System.out.println("UnionFind : " + testUF(uf, m) + " s"); 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-About-Union-Find/src/main/java/UF.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 接口功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/9 15:56 12 | */ 13 | public interface UF { 14 | 15 | int getSize(); 16 | boolean isConnected(int p, int q); 17 | void unionElements(int p, int q); 18 | } 19 | -------------------------------------------------------------------------------- /11-Union-Find/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 11-Union-Find 14 | pom 15 | 1.0-SNAPSHOT 16 | 17 | 01-What-is-Union-Find 18 | 02-Quick-Find 19 | 03-Quick-Union 20 | 04-Optimized-by-Size 21 | 05-Optimized-by-Rank 22 | 06-Path-Compression 23 | 07-More-About-Union-Find 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /12-AVL-Tree/02-Calculating-Balance-Factor/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12-AVL-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 02-Calculating-Balance-Factor 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /12-AVL-Tree/02-Calculating-Balance-Factor/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /12-AVL-Tree/02-Calculating-Balance-Factor/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/12 15:23 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /12-AVL-Tree/03-Checking-Banlance-and-Binary-Search-Property/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12-AVL-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 03-Checking-Banlance-and-Binary-Search-Property 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 11 18 | 11 19 | 11 20 | 21 | 22 | -------------------------------------------------------------------------------- /12-AVL-Tree/03-Checking-Banlance-and-Binary-Search-Property/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /12-AVL-Tree/03-Checking-Banlance-and-Binary-Search-Property/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/12 15:23 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /12-AVL-Tree/04-Rotation-Operations/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12-AVL-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 04-Rotation-Operations 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 11 18 | 11 19 | 11 20 | 21 | -------------------------------------------------------------------------------- /12-AVL-Tree/04-Rotation-Operations/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /12-AVL-Tree/04-Rotation-Operations/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/12 15:23 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /12-AVL-Tree/05-The-Implementation-Left-Rotation-Right-Rotation/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12-AVL-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-The-Implementation-Left-Rotation-Right-Rotation 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /12-AVL-Tree/05-The-Implementation-Left-Rotation-Right-Rotation/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /12-AVL-Tree/05-The-Implementation-Left-Rotation-Right-Rotation/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/12 15:23 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /12-AVL-Tree/06-LR-and-RL/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12-AVL-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 06-LR-and-RL 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /12-AVL-Tree/06-LR-and-RL/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /12-AVL-Tree/06-LR-and-RL/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/12 15:23 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /12-AVL-Tree/07-Remove-Elements-In-AVLTree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12-AVL-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 07-Remove-Elements-In-AVLTree 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /12-AVL-Tree/07-Remove-Elements-In-AVLTree/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /12-AVL-Tree/07-Remove-Elements-In-AVLTree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/12 15:23 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/08-Map-and-Set-In-AVL-Tree.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12-AVL-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 08-Map-and-Set-In-AVL-Tree 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/AVLMap.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/12/21 10:04 12 | */ 13 | public class AVLMap, V> implements Map { 14 | 15 | private AVLTree avl; 16 | 17 | public AVLMap() { 18 | avl = new AVLTree<>(); 19 | } 20 | 21 | @Override 22 | public void add(K key, V value) { 23 | avl.add(key, value); 24 | } 25 | 26 | @Override 27 | public boolean contains(K key) { 28 | return avl.contains(key); 29 | } 30 | 31 | @Override 32 | public V get(K key) { 33 | return avl.get(key); 34 | } 35 | 36 | @Override 37 | public void set(K key, V newValue) { 38 | avl.set(key, newValue); 39 | } 40 | 41 | @Override 42 | public V remove(K key) { 43 | return avl.remove(key); 44 | } 45 | 46 | @Override 47 | public int getSize() { 48 | return avl.getSize(); 49 | } 50 | 51 | @Override 52 | public boolean isEmpty() { 53 | return avl.isEmpty(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/AVLSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/12/21 10:09 12 | */ 13 | public class AVLSet> implements Set { 14 | 15 | private AVLTree avl; 16 | 17 | public AVLSet() { 18 | avl = new AVLTree<>(); 19 | } 20 | 21 | @Override 22 | public void add(E e) { 23 | avl.add(e, null); 24 | } 25 | 26 | @Override 27 | public boolean contains(E e) { 28 | return avl.contains(e); 29 | } 30 | 31 | @Override 32 | public void remove(E e) { 33 | avl.remove(e); 34 | } 35 | 36 | @Override 37 | public int getSize() { 38 | return 0; 39 | } 40 | 41 | @Override 42 | public boolean isEmpty() { 43 | return avl.isEmpty(); 44 | } 45 | 46 | public static void main(String[] args) { 47 | AVLSet set = new AVLSet<>(); 48 | set.add("111"); 49 | System.out.println(set); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, TaoDing 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/11/12 15:23 12 | */ 13 | public class Main { 14 | } 15 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | boolean contains(K key); 5 | V get(K key); 6 | void set(K key, V newValue); 7 | V remove(K key); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/TestMapMain.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/12/21 10:07 14 | */ 15 | public class TestMapMain { 16 | 17 | private static double testMap(Map map, String filename){ 18 | 19 | long startTime = System.nanoTime(); 20 | 21 | System.out.println(filename); 22 | ArrayList words = new ArrayList<>(); 23 | if(FileOperation.readFile(filename, words)) { 24 | System.out.println("Total words: " + words.size()); 25 | 26 | for (String word : words){ 27 | if(map.contains(word)) 28 | map.set(word, map.get(word) + 1); 29 | else 30 | map.add(word, 1); 31 | } 32 | 33 | System.out.println("Total different words: " + map.getSize()); 34 | System.out.println("Frequency of PRIDE: " + map.get("pride")); 35 | System.out.println("Frequency of PREJUDICE: " + map.get("prejudice")); 36 | } 37 | 38 | long endTime = System.nanoTime(); 39 | 40 | return (endTime - startTime) / 1000000000.0; 41 | } 42 | 43 | public static void main(String[] args) { 44 | 45 | String filename = "d:\\todo\\pride-and-prejudice.txt"; 46 | 47 | AVLMap avlMap = new AVLMap<>(); 48 | double time3 = testMap(avlMap, filename); 49 | System.out.println("AVL Map: " + time3 + " s"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-In-AVL-Tree/src/main/java/TestSetMain.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class TestSetMain { 4 | 5 | private static double testSet(Set set, String filename){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | System.out.println(filename); 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile(filename, words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | for (String word : words) 15 | set.add(word); 16 | System.out.println("Total different words: " + set.getSize()); 17 | } 18 | 19 | long endTime = System.nanoTime(); 20 | 21 | return (endTime - startTime) / 1000000000.0; 22 | } 23 | 24 | public static void main(String[] args) { 25 | 26 | String filename = "d:\\todo\\pride-and-prejudice.txt"; 27 | 28 | AVLSet avlSet = new AVLSet<>(); 29 | double time3 = testSet(avlSet, filename); 30 | System.out.println("AVL Set: " + time3 + " s"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /12-AVL-Tree/Chapter-12-watermarked.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/12-AVL-Tree/Chapter-12-watermarked.pdf -------------------------------------------------------------------------------- /12-AVL-Tree/README.md: -------------------------------------------------------------------------------- 1 | ## AVL树 2 | 3 | ### 定义 4 | 5 | 对于任意一个节点,左子树和右子树的高度差不能超过1。 6 | 7 | 平衡二叉树的高度和节点数量之间的关系是O(logn)的关系。 -------------------------------------------------------------------------------- /12-AVL-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 12-AVL-Tree 14 | pom 15 | 1.0-SNAPSHOT 16 | 17 | 02-Calculating-Balance-Factor 18 | 03-Checking-Banlance-and-Binary-Search-Property 19 | 04-Rotation-Operations 20 | 05-The-Implementation-Left-Rotation-Right-Rotation 21 | 06-LR-and-RL 22 | 07-Remove-Elements-In-AVLTree 23 | 08-Map-and-Set-In-AVL-Tree 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/03-The-Equivalence-of-RBTree-and-2-3-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13-Red-Black-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 03-The-Equivalence-of-RBTree-and-2-3-Tree 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/03-The-Equivalence-of-RBTree-and-2-3-Tree/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /13-Red-Black-Tree/03-The-Equivalence-of-RBTree-and-2-3-Tree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/05-Keep-Root-Black-and-Left-Rotation/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13-Red-Black-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-Keep-Root-Black-and-Left-Rotation 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/05-Keep-Root-Black-and-Left-Rotation/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /13-Red-Black-Tree/05-Keep-Root-Black-and-Left-Rotation/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/06-Flip-Color-and-Right-Rotation/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13-Red-Black-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 06-Flip-Color-and-Right-Rotation 13 | 14 | 15 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/06-Flip-Color-and-Right-Rotation/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /13-Red-Black-Tree/06-Flip-Color-and-Right-Rotation/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/07-Adding-in-Red-Black-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13-Red-Black-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 07-Adding-in-Red-Black-Tree 13 | 14 | 15 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/07-Adding-in-Red-Black-Tree/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /13-Red-Black-Tree/07-Adding-in-Red-Black-Tree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/08-The-Performance-of-Red-Black-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13-Red-Black-Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 08-The-Performance-of-Red-Black-Tree 13 | 14 | 15 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/08-The-Performance-of-Red-Black-Tree/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /13-Red-Black-Tree/08-The-Performance-of-Red-Black-Tree/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 13-Red-Black-Tree 14 | pom 15 | 1.0-SNAPSHOT 16 | 17 | 03-The-Equivalence-of-RBTree-and-2-3-Tree 18 | 05-Keep-Root-Black-and-Left-Rotation 19 | 06-Flip-Color-and-Right-Rotation 20 | 07-Adding-in-Red-Black-Tree 21 | 08-The-Performance-of-Red-Black-Tree 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /14-Hash-Table/01-Hash-Table-Basics/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14-Hash-Table 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 01-Hash-Table-Basics 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /14-Hash-Table/01-Hash-Table-Basics/src/main/java/Solution.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/12/21 11:16 12 | */ 13 | public class Solution { 14 | 15 | public static int firstUniqChar(String s) { 16 | int[] freq = new int[26]; 17 | for (int i = 0; i < s.length(); i++) { 18 | freq[s.charAt(i) - 'a']++; 19 | } 20 | for (int i = 0; i < s.length(); i++) { 21 | if (freq[s.charAt(i) - 'a'] == 1) { 22 | return i; 23 | } 24 | } 25 | return -1; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /14-Hash-Table/03-Hash-Function-In-Java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14-Hash-Table 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 03-Hash-Function-In-Java 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /14-Hash-Table/03-Hash-Function-In-Java/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/12/21 13:56 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | Student s1 = new Student(1, 2, "leon", "keh"); 17 | Student s2 = new Student(1, 2, "leon", "keh"); 18 | System.out.println(s1.equals(s2)); 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /14-Hash-Table/03-Hash-Function-In-Java/src/main/java/Student.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | /** 8 | * 类功能描述 9 | * 10 | * @author Leon 11 | * @version 2018/12/21 14:31 12 | */ 13 | public class Student { 14 | 15 | int grade; 16 | int cls; 17 | String firstName; 18 | String lastName; 19 | 20 | public Student(int grade, int cls, String firstName, String lastName) { 21 | this.grade = grade; 22 | this.cls = cls; 23 | this.firstName = firstName; 24 | this.lastName = lastName; 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | int B = 31; 30 | int hash = 0; 31 | hash = hash * B + ((Integer) grade).hashCode(); 32 | hash = hash * B + ((Integer) cls).hashCode(); 33 | hash = hash * B + firstName.hashCode(); 34 | hash = hash * B + lastName.hashCode(); 35 | return hash; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object obj) { 40 | if (null == obj) { 41 | return false; 42 | } 43 | 44 | if (obj == this) { 45 | return true; 46 | } 47 | 48 | if (this.getClass() != obj.getClass()) { 49 | return false; 50 | } 51 | 52 | Student another = (Student) obj; 53 | return another.grade == this.grade && 54 | another.cls == this.cls && 55 | another.firstName.equals(this.firstName) && 56 | another.lastName.equals(this.lastName); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /14-Hash-Table/05-HashTable-Implementation/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14-Hash-Table 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 05-HashTable-Implementation 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /14-Hash-Table/05-HashTable-Implementation/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /14-Hash-Table/05-HashTable-Implementation/src/main/java/HashTable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/12/26 14:42 14 | */ 15 | public class HashTable { 16 | 17 | private TreeMap[] hashtable; 18 | private int size; 19 | private int M; 20 | 21 | public HashTable(int M) { 22 | this.M = M; 23 | size = 0; 24 | hashtable = new TreeMap[M]; 25 | for (int i = 0; i < M; i++) { 26 | hashtable[i] = new TreeMap<>(); 27 | } 28 | } 29 | 30 | public HashTable() { 31 | this(97); 32 | } 33 | 34 | public int hash(K key) { 35 | return (key.hashCode() & 0x7fffffff) % M; 36 | } 37 | 38 | public void add(K key, V value) { 39 | TreeMap treeMap = hashtable[hash(key)]; 40 | if (treeMap.containsKey(key)) { 41 | treeMap.put(key, value); 42 | } else { 43 | treeMap.put(key,value); 44 | size++; 45 | } 46 | } 47 | 48 | 49 | public V remove(K key) { 50 | V ret = null; 51 | TreeMap map = hashtable[hash(key)]; 52 | if (map.containsKey(key)) { 53 | map.remove(key); 54 | size--; 55 | } 56 | return ret; 57 | } 58 | 59 | public void set(K key,V value) { 60 | TreeMap map = hashtable[hash(key)]; 61 | if (!map.containsKey(key)) { 62 | throw new IllegalArgumentException(key + " doesn't exist!"); 63 | } 64 | map.put(key,value); 65 | } 66 | 67 | public boolean contains(K key) { 68 | return hashtable[hash(key)].containsKey(key); 69 | } 70 | 71 | public V get(K key) { 72 | return hashtable[hash(key)].get(key); 73 | } 74 | 75 | 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /14-Hash-Table/05-HashTable-Implementation/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/12/26 14:41 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | 19 | System.out.println("Pride and Prejudice"); 20 | 21 | ArrayList words = new ArrayList<>(); 22 | if(FileOperation.readFile("d:\\todo\\pride-and-prejudice.txt", words)) { 23 | System.out.println("Total words: " + words.size()); 24 | 25 | // Collections.sort(words); 26 | 27 | // Test BST 28 | long startTime = System.nanoTime(); 29 | 30 | long endTime = System.nanoTime(); 31 | 32 | // Test HashTable 33 | startTime = System.nanoTime(); 34 | 35 | // HashTable ht = new HashTable<>(); 36 | HashTable ht = new HashTable<>(131071); 37 | for (String word : words) { 38 | if (ht.contains(word)) 39 | ht.set(word, ht.get(word) + 1); 40 | else 41 | ht.add(word, 1); 42 | } 43 | 44 | for(String word: words) 45 | ht.contains(word); 46 | 47 | endTime = System.nanoTime(); 48 | 49 | double time = (endTime - startTime) / 1000000000.0; 50 | System.out.println("HashTable: " + time + " s"); 51 | } 52 | 53 | System.out.println(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /14-Hash-Table/06-Resizing-in-Hash-Table/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14-Hash-Table 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 06-Resizing-in-Hash-Table 14 | 1.0-SNAPSHOT 15 | 16 | 17 | -------------------------------------------------------------------------------- /14-Hash-Table/06-Resizing-in-Hash-Table/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /14-Hash-Table/06-Resizing-in-Hash-Table/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/12/26 14:41 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | 19 | System.out.println("Pride and Prejudice"); 20 | 21 | ArrayList words = new ArrayList<>(); 22 | if(FileOperation.readFile("d:\\todo\\pride-and-prejudice.txt", words)) { 23 | System.out.println("Total words: " + words.size()); 24 | 25 | // Collections.sort(words); 26 | 27 | // Test BST 28 | long startTime = System.nanoTime(); 29 | 30 | long endTime = System.nanoTime(); 31 | 32 | // Test HashTable 33 | startTime = System.nanoTime(); 34 | 35 | // HashTable ht = new HashTable<>(); 36 | HashTable ht = new HashTable<>(131071); 37 | for (String word : words) { 38 | if (ht.contains(word)) 39 | ht.set(word, ht.get(word) + 1); 40 | else 41 | ht.add(word, 1); 42 | } 43 | 44 | for(String word: words) 45 | ht.contains(word); 46 | 47 | endTime = System.nanoTime(); 48 | 49 | double time = (endTime - startTime) / 1000000000.0; 50 | System.out.println("HashTable: " + time + " s"); 51 | } 52 | 53 | System.out.println(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /14-Hash-Table/07-More-About-in-Resizing-Hash-Table/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14-Hash-Table 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 07-More-About-in-Resizing-Hash-Table 13 | 14 | 15 | -------------------------------------------------------------------------------- /14-Hash-Table/07-More-About-in-Resizing-Hash-Table/src/main/java/FileOperation.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedInputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | // 文件相关操作 10 | public class FileOperation { 11 | 12 | // 读取文件名称为filename中的内容,并将其中包含的所有词语放进words中 13 | public static boolean readFile(String filename, ArrayList words){ 14 | 15 | if (filename == null || words == null){ 16 | System.out.println("filename is null or words is null"); 17 | return false; 18 | } 19 | 20 | // 文件读取 21 | Scanner scanner; 22 | 23 | try { 24 | File file = new File(filename); 25 | if(file.exists()){ 26 | FileInputStream fis = new FileInputStream(file); 27 | scanner = new Scanner(new BufferedInputStream(fis), "UTF-8"); 28 | scanner.useLocale(Locale.ENGLISH); 29 | } 30 | else 31 | return false; 32 | } 33 | catch(IOException ioe){ 34 | System.out.println("Cannot open " + filename); 35 | return false; 36 | } 37 | 38 | // 简单分词 39 | // 这个分词方式相对简陋, 没有考虑很多文本处理中的特殊问题 40 | // 在这里只做demo展示用 41 | if (scanner.hasNextLine()) { 42 | 43 | String contents = scanner.useDelimiter("\\A").next(); 44 | 45 | int start = firstCharacterIndex(contents, 0); 46 | for (int i = start + 1; i <= contents.length(); ) 47 | if (i == contents.length() || !Character.isLetter(contents.charAt(i))) { 48 | String word = contents.substring(start, i).toLowerCase(); 49 | words.add(word); 50 | start = firstCharacterIndex(contents, i); 51 | i = start + 1; 52 | } else 53 | i++; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | // 寻找字符串s中,从start的位置开始的第一个字母字符的位置 60 | private static int firstCharacterIndex(String s, int start){ 61 | 62 | for( int i = start ; i < s.length() ; i ++ ) 63 | if( Character.isLetter(s.charAt(i)) ) 64 | return i; 65 | return s.length(); 66 | } 67 | } -------------------------------------------------------------------------------- /14-Hash-Table/07-More-About-in-Resizing-Hash-Table/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2018, LeonKeh 3 | *

4 | * All Rights Reserved. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 类功能描述 11 | * 12 | * @author Leon 13 | * @version 2018/12/26 14:41 14 | */ 15 | public class Main { 16 | 17 | public static void main(String[] args) { 18 | 19 | System.out.println("Pride and Prejudice"); 20 | 21 | ArrayList words = new ArrayList<>(); 22 | if(FileOperation.readFile("d:\\todo\\pride-and-prejudice.txt", words)) { 23 | System.out.println("Total words: " + words.size()); 24 | 25 | // Collections.sort(words); 26 | 27 | // Test BST 28 | long startTime = System.nanoTime(); 29 | 30 | long endTime = System.nanoTime(); 31 | 32 | // Test HashTable 33 | startTime = System.nanoTime(); 34 | 35 | // HashTable ht = new HashTable<>(); 36 | HashTable ht = new HashTable<>(131071); 37 | for (String word : words) { 38 | if (ht.contains(word)) 39 | ht.set(word, ht.get(word) + 1); 40 | else 41 | ht.add(word, 1); 42 | } 43 | 44 | for(String word: words) 45 | ht.contains(word); 46 | 47 | endTime = System.nanoTime(); 48 | 49 | double time = (endTime - startTime) / 1000000000.0; 50 | System.out.println("HashTable: " + time + " s"); 51 | } 52 | 53 | System.out.println(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /14-Hash-Table/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.gyoomi 13 | 14-Hash-Table 14 | pom 15 | 1.0-SNAPSHOT 16 | 17 | 01-Hash-Table-Basics 18 | 03-Hash-Function-In-Java 19 | 05-HashTable-Implementation 20 | 06-Resizing-in-Hash-Table 21 | 07-More-About-in-Resizing-Hash-Table 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /15-BTree/01-The-Basic-of-BTree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15-BTree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 01-The-Basic-of-BTree 13 | 14 | 15 | -------------------------------------------------------------------------------- /15-BTree/01-The-Basic-of-BTree/src/main/java/BTreeBasic.java: -------------------------------------------------------------------------------- 1 | /** 2 | * B-tree树即B树,B即Balanced,平衡的意思。因为B树的原英文名称为B-tree. 3 | * 4 | * 是一种平衡的多路查找树。 5 | * 2-3树和2-3-4树都是B树的特例。结点最大孩子数目称为B树的阶,因此,2-3树是3阶B树; 6 | * 2-3-4树是4阶B树。 7 | * 8 | * 一个m阶B树有如下属性: 9 | * 1)如果根节点不是叶子节点,则其至少有两个子树; 10 | * 2)每一个非根的分支结点都有k-1个元素和k个孩子;其中[m/2]<=k<=m. 11 | * 每个叶子结点n都有k-1个元素,其中[m/2]<=k<=m 12 | * 3)所有的叶子结点都位于同一层次 13 | * 4)所有分支结点包含以下信息数据(n,A0,K1,A1,K2,A2,...Kn,An)。 14 | * 其中:K(i)(i=1,2,3,..n)为关键字,且K(i) < K(i+1) [i=1,2,3...n]; 15 | * A(i)(i=1,2,3...n)为指向子树根结点的指针,且指针A(i-1)所指子树中所有结点的关键字均小于K(i)[i=1,2,3...n] 16 | * A(n)所指子树中所有结点的关键字均大于K(n),n([m/2]-1 <= n <= m-1)为关键字的个数(或n+1为子树个数) 17 | * 18 | * 19 | * 20 | * 21 | * 22 | * @author Leon 23 | * @version 2019/4/28 22:50 24 | */ 25 | public class BTreeBasic { 26 | 27 | public static void main(String[] args) throws Exception { 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /15-BTree/01-The-Basic-of-BTree/src/main/java/README.md: -------------------------------------------------------------------------------- 1 | ## B树 2 | ### 一、概念 3 | B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个), 4 | 数据库索引技术里大量使用者B树和B+树的数据结构,让我们来看看他有什么特点。 5 | 6 | ### 二、规则 7 | 1. 排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则; 8 | 9 | 2. 子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外 10 | (注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉); 11 | 12 | 3. 关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个 13 | (注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2); 14 | 15 | 4. 所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针 16 | 只不过其指针地址都为null对应下图最后一层节点的空格子; 17 | 18 | 最后我们用一个图和一个实际的例子来理解B树(这里为了理解方便我就直接用实际字母的大小来排列C>B>A)。 19 | 20 | ![](./asserts/001.png) 21 | 22 | ### 三、B树的插入节点流程 23 | 定义一个5阶树(平衡5路查找树;),现在我们要把3、8、31、11、23、29、50、28 这些数字构建出一个5阶树出来。 24 | 25 | #### 遵循规则: 26 | 27 | 1. 节点拆分规则:当前是要组成一个5路查找树,那么此时m=5,关键字数必须<=5-1(这里关键字数>4就要进行节点拆分); 28 | 29 | 2. 排序规则:满足节点本身比左边节点大,比右边节点小的排序规则。 30 | 31 | #### 插入过程: 32 | 33 | 1. 先插入 3、8、31、11 34 | 35 | ![](./asserts/002.png) 36 | 37 | 2. 再插入23、29 38 | 39 | ![](./asserts/003.png) 40 | 41 | 3. 再插入50、28 42 | 43 | ![](./asserts/004.png) 44 | ### 四、B树的查询流程 45 | 46 | ![](./asserts/001.png) 47 | 48 | **如上图我要从上图中找到E字母,查找流程如下** 49 | 50 | 1. 获取根节点的关键字进行比较,当前根节点关键字为M,E 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 15-BTree 13 | pom 14 | 15 | 01-The-Basic-of-BTree 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /15-BTree/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | test=test -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 16-B+Tree 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 01-The-Basic-of-B+Tree 13 | 14 | 15 | -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/001.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/002.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/003.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/004.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/005.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/006.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/007.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/008.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/009.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/010.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/011.png -------------------------------------------------------------------------------- /16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyoomi/Data-Structures/e0f76a02007b91d950629be5c19e4bbe120bd947/16-B+Tree/01-The-Basic-of-B+Tree/src/main/java/asserts/012.png -------------------------------------------------------------------------------- /16-B+Tree/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Data-Structures 7 | com.gyoomi 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | 16-B+Tree 13 | pom 14 | 15 | 01-The-Basic-of-B+Tree 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.gyoomi 8 | Data-Structures 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | 13 | 1.8 14 | 1.8 15 | 16 | 17 | 07-Set-and-Map 18 | 08-Heap-And-Priority-Queue 19 | 09-Segment-Tree 20 | 10-Trie 21 | 11-Union-Find 22 | 12-AVL-Tree 23 | 14-Hash-Table 24 | 13-Red-Black-Tree 25 | 15-BTree 26 | 16-B+Tree 27 | 28 | --------------------------------------------------------------------------------