├── .gitignore ├── README.md ├── dart ├── 01-Linear-Search │ └── LinearSearch.dart ├── 02-Selection-Sort │ ├── Selection-sort.dart │ └── SortingHelper.dart ├── 03-Insertion-Sort │ ├── ArrayGenerator.dart │ ├── InsertionSort.dart │ └── SortingHelper.dart ├── 04-Stack-Queue │ ├── ArrayQueue.dart │ ├── ArrayStack.dart │ ├── LoopQueue.dart │ ├── Main.dart │ ├── Queue.dart │ └── Stack.dart ├── 05-LinkedList │ ├── LinkedList.dart │ ├── LinkedListQueue.dart │ ├── LinkedListStatck.dart │ ├── Queue.dart │ ├── Stack.dart │ └── main.dart ├── 06-Recursion │ ├── ListNode.dart │ ├── Solution3.dart │ └── Sum.dart ├── 07-MergeSort-More │ ├── ArrayGenerator.dart │ ├── MergeSort.dart │ └── SortingHelper.dart ├── 07-MergeSort │ ├── ArrayGenerator.dart │ ├── MergeSort.dart │ └── SortingHelper.dart ├── 08-QuickSort-More │ ├── ArrayGenerator.dart │ ├── QuickSort2way.dart │ ├── QuickSort3way.dart │ └── SortingHelper.dart ├── 08-QuickSort │ ├── ArrayGenerator.dart │ ├── QuickSort.dart │ └── SortingHelper.dart ├── 09-Binary-Search-More │ └── up │ │ ├── ArrayGenerator.dart │ │ ├── BinarySearchCeil.dart │ │ ├── BinarySearchFloor.dart │ │ ├── BinarySearchLowerCeil.dart │ │ └── BinarySearchUp.dart ├── 09-Binary-Search │ ├── ArrayGenerator.dart │ └── BinarySearchR.dart ├── 10-Binary-Search-Tree │ ├── BST.dart │ ├── LinkedList.dart │ ├── LinkedListQueue.dart │ ├── LinkedListStatck.dart │ ├── Main.dart │ ├── Queue.dart │ └── Stack.dart ├── 11-Set-And-Map │ ├── BST.dart │ ├── BSTMap.dart │ ├── BSTSet.dart │ ├── FileOperator.dart │ ├── LinkedList.dart │ ├── LinkedListMap.dart │ ├── LinkedListQueue.dart │ ├── LinkedListStatck.dart │ ├── Main.dart │ ├── Map.dart │ ├── Queue.dart │ ├── Set.dart │ ├── Stack.dart │ ├── text1.txt │ └── text2.txt ├── 12-Heap │ ├── HeapSort.dart │ ├── Main.dart │ ├── MaxHeap.dart │ ├── MinHeap.dart │ └── SortingHelper.dart ├── 13-Priority-Queue │ ├── MaxHeap.dart │ ├── PriorityQueue.dart │ └── Queue.dart ├── 14-Bubble-Sort │ ├── BubblSort.dart │ └── SortingHelper.dart ├── 15-Shell-Sort │ ├── ArrayGenerator.dart │ ├── ShellSort.dart │ └── SortingHelper.dart ├── 16-Segment-Tree │ ├── Main.dart │ ├── Merger.dart │ └── Segment.dart ├── 17-Trie │ ├── FileOperator.dart │ ├── Main.dart │ ├── Trie.dart │ ├── text1.txt │ └── text2.txt ├── 18-Union-Find │ ├── Main.dart │ ├── UF.dart │ ├── UnionFind1.dart │ ├── UnionFind2.dart │ ├── UnionFind3.dart │ ├── UnionFind4.dart │ ├── UnionFind5.dart │ └── UnionFind6.dart ├── 19-AVL-Tree │ ├── AVLTree.dart │ ├── BST.dart │ ├── FileOperator.dart │ ├── Main.dart │ ├── text1.txt │ └── text2.txt ├── 20-Red-Black-Tree │ ├── AVLTree.dart │ ├── BST.dart │ ├── FileOperator.dart │ ├── Main.dart │ ├── Main2.dart │ ├── RBTree.dart │ ├── text1.txt │ └── text2.txt ├── 21-Hash-Table │ ├── AVLTree.dart │ ├── BST.dart │ ├── FileOperator.dart │ ├── HashTable.dart │ ├── HashTableSec.dart │ ├── Main.dart │ ├── RBTree.dart │ ├── Solution.dart │ ├── text1.txt │ └── text2.txt ├── 22-CountingSort-And-RadixSort │ ├── ArrayGenerator.dart │ ├── LSDSort.dart │ ├── Main.dart │ ├── ShellSort.dart │ ├── Solution.dart │ ├── SortingHelper.dart │ └── Student.dart ├── 23-MSDSort-And-BucketSort │ ├── ArrayGenerator.dart │ ├── BucketSort.dart │ ├── MSDSort.dart │ ├── MergeSort.dart │ ├── ShellSort.dart │ └── SortingHelper.dart ├── 24-SubString-Match │ ├── FileOperator.dart │ ├── LC1392-hash.dart │ ├── LC1392.dart │ ├── LC187-RollingHash.dart │ ├── LC187.dart │ ├── Solution.dart │ ├── Solution2.dart │ ├── SubstringMatch.dart │ ├── SubstringMatchHelper.dart │ ├── text1.txt │ └── text2.txt ├── 25-GraphBascis │ ├── AdjList.dart │ ├── AdjMatrix.dart │ ├── AdjSet.dart │ ├── FileOperator.dart │ ├── Graph.dart │ ├── ListItem.dart │ └── g.txt ├── 26-GraphDFS │ ├── AdjMatrix.dart │ ├── AdjMatrixDFS.dart │ ├── ArrayStack.dart │ ├── Graph.dart │ ├── GraphDFS.dart │ ├── GraphDFSnr.dart │ ├── Stack.dart │ └── g.txt ├── 27-GraphDFS-Application │ ├── BipartitionDetection.dart │ ├── CC.dart │ ├── CycleDetection.dart │ ├── Graph.dart │ ├── GraphDFS.dart │ ├── SingleSourcePath.dart │ ├── g.txt │ ├── g2.txt │ └── g3.txt ├── 28-Graph-BFS │ ├── BipartitionDetection.dart │ ├── CC.dart │ ├── CycleDetection.dart │ ├── Graph.dart │ ├── GraphBFS.dart │ ├── SingleSourcePath.dart │ ├── g.txt │ ├── g2.txt │ └── g3.txt ├── 29-Brigde-And-Cut-Points │ ├── Edge.dart │ ├── FindBridges.dart │ ├── FindCutPoints.dart │ ├── Graph.dart │ ├── g.txt │ ├── g2.txt │ ├── g3.txt │ ├── g4.txt │ └── tree.txt ├── 30-Minimum-Tree-Spanning │ ├── CC.dart │ ├── Edge.dart │ ├── Graph.dart │ ├── Kruskal.dart │ ├── Prim.dart │ ├── UF.dart │ ├── WeightedEdge.dart │ ├── WeightedGraph.dart │ └── g.txt └── Dart-Basic.iml └── python ├── BST.py ├── __pycache__ └── sort.cpython-37.pyc ├── linkedlist.py ├── loopqueue.py ├── multiSort.py ├── queue.py └── stack.py /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://www.dartlang.org/tools/private-files.html 2 | 3 | # Files and directories created by pub 4 | .packages 5 | .pub/ 6 | build/ 7 | # If you're building an application, you may want to check-in your pubspec.lock 8 | pubspec.lock 9 | 10 | # Directory created by dartdoc 11 | # If you don't generate documentation locally you can remove this line. 12 | doc/api/ 13 | .idea/ 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AlgorithmAndDataArchitecture 2 | 3 |

使用Python、Flutter的Dart语言重写数据结构与算法

4 | 5 | 1. **[Dart,Python]线性搜索** 6 | 2. **[Dart,Python]选择排序** 7 | 3. **[Dart,Python]插入排序** 8 | 4. **[Dart,Python]栈,队列,循环队列** 9 | 5. **[Dart,Python]链表,链表实现栈,链表实现队列** 10 | 6. **[Dart,Python]递归** 11 | 7. **[Dart,Python]归并排序** 12 | 8. **[Dart,Python]快速排序** 13 | 9. **[Dart,Python]二分搜索** 14 | 10. **[Dart,Python]二分搜索树** 15 | 11. 集合 和 映射 16 | 12. 堆 17 | 13. 优先队列 18 | 14. **[Dart,Python]冒泡排序** 19 | 15. **[Dart,Python]希尔排序** 20 | 16. 线段树 21 | 17. Trie字典树 22 | 18. 并查集 23 | 19. AVL树 24 | 20. 红黑树 25 | 21. 哈希表 26 | 22. 计数排序、LSD基数排序 27 | 23. MSD排序,桶排序 28 | 24. 字符串匹配 29 | 25. 图的邻接矩阵,邻接表 30 | 26. 图的深度优先遍历 31 | 27. 图的深度优先遍历应用 32 | 1. 图的联通分量 33 | 2. 图的单源路径问题 34 | 3. 无向图的环检测 35 | 4. 二分图检测 36 | 28. 图的广度优先遍历 37 | 1. 图的单源路径问题 38 | 2. 图的联通分量 39 | 3. 无向图的环检测 40 | 4. 二分图检测 41 | 29. 桥和割点 42 | 30. 最小生成树 43 | 44 | #### SDK版本 45 | 1. 版本:2.12.3 46 | 2. Java版本课程地址:[慕课网算法与数据结构](https://class.imooc.com/sale/datastructure) 47 | 3. Java版本图课程:[慕课网图论算法](https://coding.imooc.com/class/370.html) 48 | -------------------------------------------------------------------------------- /dart/01-Linear-Search/LinearSearch.dart: -------------------------------------------------------------------------------- 1 | void main(){ 2 | var data = {24, 18, 12, 9, 16, 66, 32, 4}; 3 | if(LinearSearch(data.toList(), 4)){ 4 | print("搜索到数字"); 5 | }else{ 6 | print("没搜索到数字"); 7 | } 8 | } 9 | bool search(List arr,Object target){ 10 | return arr.contains(target); 11 | } 12 | 13 | bool LinearSearch(List arr,Object target){ 14 | for(int i =0;i 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/03-Insertion-Sort/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = [n]; 7 | for(int i = 0;i[n]; 15 | Random random = new Random(); 16 | for(int i = 0; i < n; i ++) 17 | arr[i] = random.nextInt(bound); 18 | return arr; 19 | } 20 | } -------------------------------------------------------------------------------- /dart/03-Insertion-Sort/InsertionSort.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 插入排序 3 | * 1、Dart自带插入排序算法 4 | * 2、手动实现插入排序算法 5 | * 3、 源码部分 6 | * dart数组天然支持泛型, 7 | * compare 是实现比对接口 8 | */ 9 | void main() { 10 | var list = [2, 4, 6, 3, 1, 5]; 11 | var list2 = ["2","4","6","3","1","5"]; 12 | var list3 = [2, 4, 6, 3, 1, 5]; 13 | sort(list); 14 | insertionSort(list2); 15 | insertionSort2(list3); 16 | } 17 | 18 | //Dart语言原生方法 19 | void sort(List arr) { 20 | print("Dart自带排序算法----------------------"); 21 | arr.sort(); 22 | arr.forEach((element) { 23 | print(element); 24 | }); 25 | 26 | } 27 | 28 | void insertionSort(List arr) { 29 | print("手动实现插入排序算法----------------------"); 30 | for (int i = 0; i < arr.length; i++) { 31 | for (int j = i; j - 1 >= 0; j--) { 32 | if (Comparable.compare(arr[j] ,arr[j - 1]) < 0) { 33 | swap(arr, j - 1, j); 34 | }else{ 35 | break; 36 | } 37 | } 38 | } 39 | arr.forEach((element) { 40 | print(element); 41 | }); 42 | 43 | } 44 | /** 45 | * 插入排序优化 46 | */ 47 | void insertionSort2(List arr) { 48 | print("手动实现优化插入排序算法----------------------"); 49 | for (int i = 0; i < arr.length; i++) { 50 | var t = arr[i]; 51 | int j ; 52 | for (j = i; j - 1 >= 0 &&(t.compareTo(arr[j - 1])<0); j--) { 53 | arr[j] = arr[j-1]; 54 | } 55 | arr[j] = t; 56 | } 57 | arr.forEach((element) { 58 | print(element); 59 | }); 60 | 61 | } 62 | 63 | void swap(arr, int i, int j) { 64 | var t = arr[i]; 65 | arr[i] = arr[j]; 66 | arr[j] = t; 67 | } 68 | 69 | // Dart 源码使用的是阀值,32 70 | // 当在32以内使用插入排序,当在32以外使用双向快排 71 | // static const int _INSERTION_SORT_THRESHOLD = 32; 72 | // /** 73 | // * Sorts all elements of the given list [:a:] according to the given 74 | // * [:compare:] function. 75 | // * 76 | // * The [:compare:] function takes two arguments [:x:] and [:y:] and returns 77 | // * -1 if [:x < y:], 78 | // * 0 if [:x == y:], and 79 | // * 1 if [:x > y:]. 80 | // * 81 | // * The function's behavior must be consistent. It must not return different 82 | // * results for the same values. 83 | // */ 84 | // static void sort(List a, int compare(E a, E b)) { 85 | // _doSort(a, 0, a.length - 1, compare); 86 | // } 87 | // 88 | // /** 89 | // * Sorts all elements in the range [:from:] (inclusive) to [:to:] (exclusive) 90 | // * of the given list [:a:]. 91 | // * 92 | // * If the given range is invalid an "OutOfRange" error is raised. 93 | // * 94 | // * See [:sort:] for requirements of the [:compare:] function. 95 | // */ 96 | // static void sortRange(List a, int from, int to, int compare(E a, E b)) { 97 | // if ((from < 0) || (to > a.length) || (to < from)) { 98 | // throw "OutOfRange"; 99 | // } 100 | // _doSort(a, from, to - 1, compare); 101 | // } 102 | // 103 | // /** 104 | // * Sorts the list in the interval [:left:] to [:right:] (both inclusive). 105 | // */ 106 | // static void _doSort( 107 | // List a, int left, int right, int compare(E a, E b)) { 108 | // if ((right - left) <= _INSERTION_SORT_THRESHOLD) { 109 | // _insertionSort(a, left, right, compare); 110 | // } else { 111 | // _dualPivotQuicksort(a, left, right, compare); 112 | // } 113 | // } 114 | // 115 | // 116 | 117 | 118 | -------------------------------------------------------------------------------- /dart/03-Insertion-Sort/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | //import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/04-Stack-Queue/ArrayQueue.dart: -------------------------------------------------------------------------------- 1 | import 'Queue.dart'; 2 | class ArrayQueue implements Queue{ 3 | 4 | List? arr; 5 | ArrayQueue(){ 6 | arr =[]; 7 | } 8 | 9 | @override 10 | dequeue() { 11 | arr!.removeAt(0); 12 | } 13 | 14 | @override 15 | void enqueue(e) { 16 | arr!.add(e); 17 | } 18 | 19 | @override 20 | getFront() { 21 | return arr![0]; 22 | } 23 | 24 | @override 25 | int getSize() { 26 | return arr!.length; 27 | } 28 | 29 | @override 30 | bool isEmpty() { 31 | return arr!.isEmpty; 32 | } 33 | 34 | @override 35 | String toString() { 36 | StringBuffer buffer = new StringBuffer(); 37 | buffer.write("Queue: "); 38 | buffer.write('front ['); 39 | for(int i = 0 ; i < arr!.length ; i ++){ 40 | buffer.write(arr![i]); 41 | if(i != arr!.length - 1) 42 | buffer.write(", "); 43 | } 44 | buffer.write("] tail"); 45 | return buffer.toString(); 46 | } 47 | } -------------------------------------------------------------------------------- /dart/04-Stack-Queue/ArrayStack.dart: -------------------------------------------------------------------------------- 1 | import 'Stack.dart'; 2 | class ArrayStack implements Stack{ 3 | 4 | List? arr; 5 | ArrayStack(){ 6 | arr =[]; 7 | } 8 | 9 | @override 10 | int getSize() { 11 | return arr!.length; 12 | } 13 | 14 | @override 15 | bool isEmpty() { 16 | return arr!.isEmpty; 17 | } 18 | 19 | @override 20 | T peek() { 21 | return arr![0]; 22 | } 23 | 24 | @override 25 | T pop() => arr!.removeLast(); 26 | 27 | @override 28 | void push(T e) { 29 | arr!.add(e); 30 | } 31 | 32 | @override 33 | String toString() { 34 | StringBuffer buffer = new StringBuffer(); 35 | buffer.write("Stack: "); 36 | buffer.write('['); 37 | for(int i = 0 ; i < arr!.length ; i ++){ 38 | buffer.write(arr![i]); 39 | if(i != arr!.length - 1) 40 | buffer.write(", "); 41 | } 42 | buffer.write("] top"); 43 | return buffer.toString(); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /dart/04-Stack-Queue/LoopQueue.dart: -------------------------------------------------------------------------------- 1 | import 'Queue.dart'; 2 | 3 | class LoopQueue implements Queue { 4 | List? arr; 5 | int front = 0, tail = 0; 6 | int size = 0; 7 | 8 | LoopQueue() { 9 | arr = List.filled(10, false); 10 | } 11 | 12 | // LoopQueue.capcity(int capacity){ 13 | // arr = List.filled(capacity+1, false); 14 | // } 15 | 16 | int getCapacity() { 17 | //目前这种方式浪费一个空间 18 | int capacity = arr!.length - 1; 19 | return capacity; 20 | } 21 | 22 | @override 23 | dequeue() { 24 | if (isEmpty()) { 25 | throw Exception("Cannot dequeue from an empty queue"); 26 | } 27 | T ret = arr![front]; 28 | arr![front] = null; 29 | front = (front + 1) % arr!.length; 30 | size--; 31 | if (size == getCapacity() / 4 && getCapacity() / 2 != 0) { 32 | resize((getCapacity() / 2) as int); 33 | } 34 | return ret; 35 | } 36 | 37 | void resize(int newCapacity) { 38 | List? newArr = List.filled(newCapacity + 1, false); 39 | for (int i = 0; i < arr!.length; i++) { 40 | newArr[i] = arr![(i + front) % arr!.length]; 41 | } 42 | arr = newArr; 43 | front = 0; 44 | tail = size; 45 | } 46 | 47 | @override 48 | void enqueue(e) { 49 | if ((tail + 1) % arr!.length == front) resize(getCapacity() * 2); 50 | arr![tail] = e; 51 | tail = (tail + 1) % arr!.length; 52 | size++; 53 | } 54 | 55 | @override 56 | getFront() { 57 | if (isEmpty()) { 58 | throw Exception("Queue is empty."); 59 | } 60 | return arr![front]; 61 | } 62 | 63 | @override 64 | int getSize() { 65 | return arr!.length; 66 | } 67 | 68 | @override 69 | bool isEmpty() { 70 | return front == tail; 71 | } 72 | 73 | @override 74 | String toString() { 75 | StringBuffer buffer = new StringBuffer(); 76 | buffer.write("Queue: size = $size , capacity = ${getCapacity()} \n"); 77 | buffer.write('front ['); 78 | for (int i = front; i != tail; i = (i + 1) % arr!.length) { 79 | buffer.write(arr![i]); 80 | if ((i + 1) % arr!.length != tail) buffer.write(", "); 81 | } 82 | buffer.write("] tail"); 83 | return buffer.toString(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /dart/04-Stack-Queue/Main.dart: -------------------------------------------------------------------------------- 1 | import 'ArrayStack.dart'; 2 | import 'ArrayQueue.dart'; 3 | import 'LoopQueue.dart'; 4 | 5 | void main() { 6 | // ArrayStack stack = new ArrayStack(); 7 | // for(int i = 0 ; i < 10 ; i ++){ 8 | // stack.push(i); 9 | // print(stack.toString()); 10 | // } 11 | // stack.pop(); 12 | // 13 | // ArrayQueue queue = new ArrayQueue(); 14 | // for(int i = 0 ; i < 20 ; i ++){ 15 | // queue.enqueue(i); 16 | // print(queue); 17 | // if(i % 3 == 2){ 18 | // print('----出栈头部元素-----'); 19 | // queue.dequeue(); 20 | // print(queue); 21 | // } 22 | // } 23 | 24 | LoopQueue loopQueue = new LoopQueue(); 25 | 26 | for (int i = 0; i < 30; i++) { 27 | loopQueue.enqueue(i); 28 | print(loopQueue); 29 | 30 | if (i % 3 == 2) { 31 | loopQueue.dequeue(); 32 | print(loopQueue); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dart/04-Stack-Queue/Queue.dart: -------------------------------------------------------------------------------- 1 | abstract class Queue{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void enqueue(T e); 5 | T dequeue(); 6 | T getFront(); 7 | } -------------------------------------------------------------------------------- /dart/04-Stack-Queue/Stack.dart: -------------------------------------------------------------------------------- 1 | abstract class Stack{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void push(T e); 5 | T pop(); 6 | T peek(); 7 | } -------------------------------------------------------------------------------- /dart/05-LinkedList/LinkedList.dart: -------------------------------------------------------------------------------- 1 | class LinkedList { 2 | _Node? _dummyHead; 3 | late int _size; 4 | 5 | LinkedList() { 6 | _dummyHead = new _Node.withEmpty(); 7 | _size = 0; 8 | } 9 | 10 | int getSize() { 11 | return _size; 12 | } 13 | 14 | bool isEmpty() { 15 | return _size == 0; 16 | } 17 | 18 | remove(int index){ 19 | if (index < 0 || index > _size) { 20 | throw Exception("Remove Failed,Illegal index"); 21 | } 22 | _Node? prev = _dummyHead; 23 | for(var i =0;i _size) { 46 | throw Exception("Add Failed,Illegal index"); 47 | } 48 | // if(index == 0){ 49 | // addFirst(t); 50 | // }else{ 51 | _Node? prev = _dummyHead; 52 | for (var i = 0; i < index; i++) { 53 | prev = prev?.next; 54 | } 55 | _Node _node = new _Node.wihtHead(t); 56 | _node.next = prev?.next; 57 | prev?.next = _node; 58 | _size++; 59 | // } 60 | } 61 | 62 | addLast(T t) { 63 | add(_size, t); 64 | } 65 | 66 | addFirst(T t) { 67 | // _Node _node =new _Node.head(t); 68 | // _node.next = _head; 69 | // _head = _node; 70 | add(0, t); 71 | } 72 | 73 | //获取链表第index位置的元素 74 | T get(int index){ 75 | if (index < 0 || index > _size) { 76 | throw Exception("Get Failed,Illegal index"); 77 | } 78 | _Node? cur = _dummyHead!.next; 79 | for(var i=0;i _size) { 93 | throw Exception("Set Failed,Illegal index"); 94 | } 95 | _Node? cur = _dummyHead!.next; 96 | for(var i =0;i"); 119 | } 120 | res.write("NULL"); 121 | return res.toString(); 122 | } 123 | } 124 | //节点 125 | class _Node { 126 | _Node? next; 127 | 128 | T? t; 129 | 130 | _Node.withEmpty(); 131 | 132 | _Node.withAll(this.t, this.next); 133 | 134 | factory _Node.wihtHead(T t) { 135 | var result = new _Node.withAll(t, null); 136 | return result; 137 | } 138 | 139 | @override 140 | String toString() { 141 | return t.toString(); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /dart/05-LinkedList/LinkedListQueue.dart: -------------------------------------------------------------------------------- 1 | import 'Queue.dart'; 2 | 3 | /** 4 | * 带尾结点的队列 5 | */ 6 | class LinkedListQueue implements Queue{ 7 | 8 | late _Node? _head; 9 | late _Node? _tail; 10 | late int _size; 11 | 12 | LinkedListQueue(){ 13 | _head = null; 14 | _tail = null; 15 | _size = 0; 16 | } 17 | 18 | @override 19 | dequeue() { 20 | if (isEmpty()) { 21 | throw Exception("Cannot dequeue from an empty queue"); 22 | } 23 | _Node retNode = _head!; 24 | _head = _head!.next; 25 | retNode.next = null; 26 | if(_head == null){ 27 | _tail =null; 28 | } 29 | _size --; 30 | return retNode.t; 31 | } 32 | 33 | @override 34 | void enqueue(e) { 35 | if(_tail == null){ 36 | _tail = _Node.wihtHead(e); 37 | _head = _tail; 38 | }else{ 39 | _tail!.next =_Node.wihtHead(e); 40 | _tail = _tail!.next; 41 | } 42 | _size++; 43 | } 44 | 45 | @override 46 | getFront() { 47 | if (isEmpty()) { 48 | throw Exception("Queue is empty"); 49 | } 50 | return _head!.t; 51 | } 52 | 53 | @override 54 | int getSize() { 55 | return _size; 56 | } 57 | 58 | @override 59 | bool isEmpty() { 60 | return _size == 0; 61 | } 62 | 63 | @override 64 | String toString() { 65 | StringBuffer res =new StringBuffer(); 66 | res.write("Queue: front "); 67 | for(_Node? cur = _head!.next ; cur != null ; cur = cur.next){ 68 | res.write(cur); 69 | res.write("->"); 70 | } 71 | res.write("NULL tail"); 72 | return res.toString(); 73 | } 74 | 75 | } 76 | 77 | //节点 78 | class _Node { 79 | _Node? next; 80 | 81 | T? t; 82 | 83 | _Node(); 84 | 85 | _Node.withAll(this.t, this.next); 86 | 87 | factory _Node.wihtHead(T t) { 88 | var result = new _Node.withAll(t, null); 89 | return result; 90 | } 91 | 92 | @override 93 | String toString() { 94 | return t.toString(); 95 | } 96 | } 97 | 98 | void main(){ 99 | LinkedListQueue queue = new LinkedListQueue(); 100 | for(int i = 0 ; i < 10 ; i ++){ 101 | queue.enqueue(i); 102 | print(queue); 103 | if(i % 3 ==2){ 104 | queue.dequeue(); 105 | print(queue); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /dart/05-LinkedList/LinkedListStatck.dart: -------------------------------------------------------------------------------- 1 | import 'Stack.dart'; 2 | import 'LinkedList.dart'; 3 | 4 | class LinkedListStack implements Stack{ 5 | 6 | LinkedList? _linkedList; 7 | 8 | LinkedListStack(){ 9 | _linkedList =new LinkedList(); 10 | } 11 | 12 | @override 13 | int getSize() { 14 | return _linkedList!.getSize(); 15 | } 16 | 17 | @override 18 | bool isEmpty() { 19 | return _linkedList!.isEmpty(); 20 | } 21 | 22 | @override 23 | peek() { 24 | return _linkedList!.getFirst(); 25 | } 26 | 27 | @override 28 | pop() { 29 | _linkedList!.removeFirst(); 30 | } 31 | 32 | @override 33 | void push(e) { 34 | _linkedList!.addFirst(e); 35 | } 36 | 37 | @override 38 | String toString() { 39 | StringBuffer res = new StringBuffer(); 40 | res.write("Stack:top "); 41 | res.write(_linkedList); 42 | return res.toString(); 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /dart/05-LinkedList/Queue.dart: -------------------------------------------------------------------------------- 1 | abstract class Queue{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void enqueue(T e); 5 | T dequeue(); 6 | T getFront(); 7 | } -------------------------------------------------------------------------------- /dart/05-LinkedList/Stack.dart: -------------------------------------------------------------------------------- 1 | abstract class Stack{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void push(T e); 5 | T pop(); 6 | T peek(); 7 | } -------------------------------------------------------------------------------- /dart/05-LinkedList/main.dart: -------------------------------------------------------------------------------- 1 | import 'LinkedList.dart'; 2 | import 'LinkedListStatck.dart'; 3 | import 'LinkedListQueue.dart'; 4 | void main(){ 5 | LinkedList linkedList = new LinkedList(); 6 | for(int i = 0 ; i < 5 ; i ++){ 7 | linkedList.addFirst(i); 8 | print(linkedList); 9 | } 10 | linkedList.add(2, 666); 11 | print(linkedList); 12 | linkedList.remove(2); 13 | print(linkedList); 14 | linkedList.removeFirst(); 15 | print(linkedList); 16 | linkedList.removeLast(); 17 | print(linkedList); 18 | 19 | LinkedListStack stack =new LinkedListStack(); 20 | for(int i = 0 ; i < 5 ; i ++){ 21 | stack.push(i); 22 | print(stack); 23 | } 24 | LinkedListQueue queue = new LinkedListQueue(); 25 | for(int i = 0 ; i < 10 ; i ++){ 26 | queue.enqueue(i); 27 | if(i % 3 ==2){ 28 | queue.dequeue(); 29 | print(queue); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /dart/06-Recursion/ListNode.dart: -------------------------------------------------------------------------------- 1 | class ListNode{ 2 | 3 | int? val; 4 | ListNode? next; 5 | 6 | ListNode(this.val); 7 | 8 | ListNode.withArray(List arr){ 9 | if(arr == null || arr.length == 0){ 10 | throw Exception("arr cannot be empty"); 11 | } 12 | this.val = arr[0]; 13 | ListNode cur = this; 14 | for(var i = 1;i"); 25 | if(cur.next !=null){ 26 | cur = cur.next!; 27 | }else{ 28 | break; 29 | } 30 | } 31 | s.write("NULL"); 32 | return s.toString(); 33 | } 34 | 35 | 36 | } -------------------------------------------------------------------------------- /dart/06-Recursion/Solution3.dart: -------------------------------------------------------------------------------- 1 | import 'ListNode.dart'; 2 | class Solution3{ 3 | 4 | static ListNode? removeElements(ListNode head,int val){ 5 | ListNode dummyHead = new ListNode(-1); 6 | dummyHead.next = head; 7 | 8 | ListNode prev = dummyHead; 9 | while(prev.next!=null){ 10 | if(prev.next!.val == val){ 11 | prev.next = prev.next!.next; 12 | }else{ 13 | prev = prev.next!; 14 | } 15 | } 16 | return dummyHead.next; 17 | // if(head == null){ 18 | // return head; 19 | // } 20 | // ListNode? res = removeElements(head.next!, val); 21 | // if(head.val == val){ 22 | // return res; 23 | // }else{ 24 | // head.next = res; 25 | // return head; 26 | // }; 27 | 28 | } 29 | } 30 | void main(){ 31 | var nums = [1,2,6,3,4,5,6]; 32 | ListNode listNode =ListNode.withArray(nums); 33 | print(listNode); 34 | 35 | ListNode? res = Solution3.removeElements(listNode, 6); 36 | print(res); 37 | 38 | } -------------------------------------------------------------------------------- /dart/06-Recursion/Sum.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 递归 3 | */ 4 | class Sum{ 5 | 6 | static int sum(List arr){ 7 | return sumRecurison(arr,0); 8 | } 9 | static int sumRecurison(List arr,int l){ 10 | if(l == arr.length){ 11 | return 0; 12 | } 13 | return arr[l]+sumRecurison(arr,l+1); 14 | } 15 | } 16 | 17 | void main(){ 18 | List nums = [1,2,3,4,5,6,7,8]; 19 | int result = Sum.sum(nums); 20 | print("结果:$result"); 21 | } 22 | -------------------------------------------------------------------------------- /dart/07-MergeSort-More/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/07-MergeSort/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i= right){ 17 | return; 18 | } 19 | int mid = ((right-left)/2).toInt() +left; 20 | _sortContent(arr, left, mid); 21 | _sortContent(arr, mid+1, right); 22 | //提前进行判断,少一步merge 23 | if(arr[mid].compareTo(arr[mid+1])>0){ 24 | _merge(arr,left,mid,right); 25 | } 26 | } 27 | 28 | static _merge(List arr,int l,int mid,int right){ 29 | // List temp = List.copyRange(arr, l, r!+1); 30 | List temp = List.filled(right+1-l, true); 31 | List.copyRange(temp, 0, arr,l,right+1); 32 | int i = l, j = mid + 1; 33 | 34 | // 每轮循环为 arr[k] 赋值 35 | for(int k = l; k <= right; k ++){ 36 | if(i > mid){ 37 | arr[k] = temp[j - l]; j ++; 38 | } 39 | else if(j > right){ 40 | arr[k] = temp[i - l]; i ++; 41 | } 42 | else if(temp[i - l].compareTo(temp[j - l]) <= 0){ 43 | arr[k] = temp[i - l]; i ++; 44 | } 45 | else{ 46 | arr[k] = temp[j - l]; j ++; 47 | } 48 | } 49 | } 50 | } 51 | void main(){ 52 | int n = 20; 53 | List arr = ArrayGenerator.generateRandomArray(n, n); 54 | MergeSort.sort(arr); 55 | print(arr); 56 | } -------------------------------------------------------------------------------- /dart/07-MergeSort/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | //import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/08-QuickSort-More/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i= r) return; 17 | 18 | int p = _partition2ways(arr, l, r, rnd); 19 | _sort2waysDetail(arr, l, p - 1, rnd); 20 | _sort2waysDetail(arr, p + 1, r, rnd); 21 | } 22 | 23 | static int _partition2ways(List arr, int l, int r, Random rnd) { 24 | int p = l + rnd.nextInt(r - l + 1); 25 | _swap(arr, l, p); 26 | // arr[l+1...i-1] <= v; arr[j+1...r] >= v 27 | int i = l + 1, j = r; 28 | while (true) { 29 | while (i <= j && arr[i].compareTo(arr[l]) < 0){ 30 | i++; 31 | } 32 | while (j >= i && arr[j].compareTo(arr[l]) > 0){ 33 | j--; 34 | } 35 | if (i >= j){ 36 | break; 37 | } 38 | _swap(arr, i, j); 39 | i++; 40 | j--; 41 | } 42 | _swap(arr, l, j); 43 | return j; 44 | } 45 | 46 | static _swap(List arr, int i, int j) { 47 | var t = arr[i]; 48 | arr[i] = arr[j]; 49 | arr[j] = t; 50 | } 51 | } 52 | 53 | void main() { 54 | int n = 100; 55 | List arr2 = ArrayGenerator.generateRandomArray(n, n); 56 | print(arr2); 57 | QuickSort2way.sort2ways(arr2); 58 | print(arr2); 59 | } 60 | -------------------------------------------------------------------------------- /dart/08-QuickSort-More/QuickSort3way.dart: -------------------------------------------------------------------------------- 1 | import 'ArrayGenerator.dart'; 2 | import 'dart:math'; 3 | /** 4 | * 三路快排 5 | */ 6 | class QuickSort3way { 7 | QuickSort3way() {} 8 | 9 | static sort3ways(List arr) { 10 | Random rnd = new Random(); 11 | _sort3waysDetail(arr, 0, arr.length - 1, rnd); 12 | } 13 | 14 | static _sort3waysDetail(List arr, int left, int right, Random rnd) { 15 | if (left >= right) return; 16 | // 生成 [l, r] 之间的随机索引 17 | int p = left + rnd.nextInt(right - left + 1); 18 | _swap(arr, left, p); 19 | // arr[l + 1, lt] < v, arr[lt + 1, i - 1] == v, arr[gt, r] > v 20 | int lt = left, i = left + 1, gt = right + 1; 21 | while(i < gt){ 22 | if(arr[i].compareTo(arr[left]) < 0){ 23 | lt ++; 24 | _swap(arr, i, lt); 25 | i ++; 26 | } 27 | else if(arr[i].compareTo(arr[left]) > 0){ 28 | gt --; 29 | _swap(arr, i, gt); 30 | } 31 | else{ // arr[i] == v 32 | i ++; 33 | } 34 | } 35 | _swap(arr, left, lt); 36 | // 递归调用 37 | _sort3waysDetail(arr, left, lt - 1, rnd); 38 | _sort3waysDetail(arr, gt, right, rnd); 39 | } 40 | 41 | static int _partition3ways(List arr, int l, int r, Random rnd) { 42 | int p = l + rnd.nextInt(r - l + 1); 43 | _swap(arr, l, p); 44 | // arr[l+1...i-1] <= v; arr[j+1...r] >= v 45 | int i = l + 1, j = r; 46 | while (true) { 47 | while (i <= j && arr[i].compareTo(arr[l]) < 0){ 48 | i++; 49 | } 50 | while (j >= i && arr[j].compareTo(arr[l]) > 0){ 51 | j--; 52 | } 53 | if (i >= j){ 54 | break; 55 | } 56 | _swap(arr, i, j); 57 | i++; 58 | j--; 59 | } 60 | _swap(arr, l, j); 61 | return j; 62 | } 63 | 64 | static _swap(List arr, int i, int j) { 65 | var t = arr[i]; 66 | arr[i] = arr[j]; 67 | arr[j] = t; 68 | } 69 | } 70 | 71 | void main() { 72 | int n = 1000; 73 | List arr2 = ArrayGenerator.generateRandomArray(n, n); 74 | print(arr2); 75 | QuickSort3way.sort3ways(arr2); 76 | print(arr2); 77 | } 78 | -------------------------------------------------------------------------------- /dart/08-QuickSort-More/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | //import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/08-QuickSort/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i= right){ 12 | return; 13 | } 14 | int p = _partition(arr, left, right); 15 | _sortDetail(arr, left, p-1); 16 | _sortDetail(arr, p+1, right); 17 | } 18 | 19 | static int _partition(List arr,int left,int right){ 20 | //优化中间值选取,采用随机方式 21 | int p = left+(new Random().nextInt(right-left+1)); 22 | _swap(arr, left, p); 23 | int j =left; 24 | for(var i = left+1;i<=right;i++){ 25 | if(arr[i].compareTo(arr[left])<0){ 26 | j++; 27 | _swap(arr,i,j); 28 | } 29 | } 30 | _swap(arr, left, j); 31 | return j; 32 | } 33 | static _swap(List arr,int i,int j){ 34 | var t =arr[i]; 35 | arr[i] = arr[j]; 36 | arr[j] = t; 37 | } 38 | } 39 | void main(){ 40 | int n =10; 41 | List arr2 = ArrayGenerator.generateRandomArray(n, n); 42 | print(arr2); 43 | QuickSort.sort(arr2); 44 | print(arr2); 45 | } -------------------------------------------------------------------------------- /dart/08-QuickSort/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | //import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/09-Binary-Search-More/up/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i(List data,T target){ 11 | 12 | int left = 0, right = data.length - 1; 13 | 14 | // 在 data[l, r] 的范围中查找 target 15 | while(left <= right){ 16 | int mid = left + ((right - left) / 2).toInt(); 17 | if(data[mid].compareTo(target) == 0) 18 | return mid; 19 | if(data[mid].compareTo(target) < 0) 20 | left = mid + 1; 21 | else 22 | right = mid - 1; 23 | } 24 | return -1; 25 | 26 | } 27 | // > target 的最小值索引 28 | static int upper(List arr,T target){ 29 | int left = 0,right = arr.length; 30 | while (left < right){ 31 | int mid = left +((right -left)/2).toInt(); 32 | if(arr[mid].compareTo(target)<=0){ 33 | left = mid +1; 34 | }else{ 35 | right = mid ; 36 | } 37 | } 38 | return left; 39 | } 40 | 41 | // > target ,返回最小值索引 42 | // == target,返回最大索引 43 | static int ceil(List arr,T target){ 44 | int u = upper(arr, target); 45 | if(u-1>= 0 && arr[u-1].compareTo(target) == 0){ 46 | return u-1; 47 | } 48 | return u; 49 | } 50 | 51 | } 52 | 53 | void main(){ 54 | // int n = 1000; 55 | // List arr2 = ArrayGenerator.generateOrderedArray(n); 56 | // print(BinarySearch.search(arr2, 50)); 57 | var arr =[1,1,3,3,5,5,7,7]; 58 | for(var i = 0;i<=6;i++){ 59 | print(BinarySearch.ceil(arr, i)); 60 | } 61 | } -------------------------------------------------------------------------------- /dart/09-Binary-Search-More/up/BinarySearchFloor.dart: -------------------------------------------------------------------------------- 1 | import 'ArrayGenerator.dart'; 2 | 3 | /** 4 | * 二分搜索 5 | */ 6 | class BinarySearch { 7 | BinarySearch() {} 8 | 9 | static int search(List data, T target) { 10 | int left = 0, right = data.length - 1; 11 | 12 | // 在 data[l, r] 的范围中查找 target 13 | while (left <= right) { 14 | int mid = left + ((right - left) / 2).toInt(); 15 | if (data[mid].compareTo(target) == 0) return mid; 16 | if (data[mid].compareTo(target) < 0) 17 | left = mid + 1; 18 | else 19 | right = mid - 1; 20 | } 21 | return -1; 22 | } 23 | 24 | // > target 的最小值索引 25 | static int upper(List arr, T target) { 26 | int left = 0, right = arr.length; 27 | while (left < right) { 28 | int mid = left + ((right - left) / 2).toInt(); 29 | if (arr[mid].compareTo(target) <= 0) { 30 | left = mid + 1; 31 | } else { 32 | right = mid; 33 | } 34 | } 35 | return left; 36 | } 37 | 38 | // > target ,返回最小值索引 39 | // == target,返回最大索引 40 | static int upper_ceil(List arr, T target) { 41 | int u = upper(arr, target); 42 | if (u - 1 >= 0 && arr[u - 1].compareTo(target) == 0) { 43 | return u - 1; 44 | } 45 | return u; 46 | } 47 | 48 | // >= target 的最小值索引 49 | static int lower_ceil(List data, T target) { 50 | int left = 0, right = data.length; 51 | // 在 data[l, r] 中寻找解 52 | while (left < right) { 53 | int mid = left + ((right - left) / 2).toInt(); 54 | if (data[mid].compareTo(target) < 0) 55 | left = mid + 1; 56 | else 57 | right = mid; 58 | } 59 | return left; 60 | } 61 | 62 | // < target 的最大值索引 63 | static int lower(List data, T target) { 64 | int left = -1, right = data.length - 1; 65 | // 在 data[l, r] 中寻找解 66 | while (left < right) { 67 | int mid = left + ((right - left + 1) / 2).toInt(); 68 | if (data[mid].compareTo(target) < 0) 69 | left = mid; 70 | else 71 | right = mid - 1; 72 | } 73 | return left; 74 | } 75 | 76 | // < target ,返回最大值索引 77 | // == target,返回最小索引 78 | static int lower_floor(List data, T target) { 79 | int l = lower(data, target); 80 | if (l + 1 < data.length && data[l + 1].compareTo(target) == 0) return l + 1; 81 | return l; 82 | } 83 | 84 | // <= target 最大索引 85 | static int upper_floor(List data, T target) { 86 | int left = -1, right = data.length - 1; 87 | // 在 data[l, r] 中寻找解 88 | while (left < right) { 89 | int mid = left + ((right - left + 1) / 2).toInt(); 90 | if (data[mid].compareTo(target) <= 0) 91 | left= mid; 92 | else 93 | right = mid - 1; 94 | } 95 | return left; 96 | } 97 | } 98 | 99 | void main() { 100 | // int n = 1000; 101 | // List arr2 = ArrayGenerator.generateOrderedArray(n); 102 | // print(BinarySearch.search(arr2, 50)); 103 | var arr = [1, 1, 3, 3, 5, 5, 7, 7]; 104 | for (var i = 0; i <= 6; i++) { 105 | print(BinarySearch.lower(arr, i)); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /dart/09-Binary-Search-More/up/BinarySearchLowerCeil.dart: -------------------------------------------------------------------------------- 1 | import 'ArrayGenerator.dart'; 2 | 3 | /** 4 | * 二分搜索 5 | */ 6 | class BinarySearch { 7 | BinarySearch() {} 8 | 9 | static int search(List data, T target) { 10 | int left = 0, right = data.length - 1; 11 | 12 | // 在 data[l, r] 的范围中查找 target 13 | while (left <= right) { 14 | int mid = left + ((right - left) / 2).toInt(); 15 | if (data[mid].compareTo(target) == 0) return mid; 16 | if (data[mid].compareTo(target) < 0) 17 | left = mid + 1; 18 | else 19 | right = mid - 1; 20 | } 21 | return -1; 22 | } 23 | 24 | // > target 的最小值索引 25 | static int upper(List arr, T target) { 26 | int left = 0, right = arr.length; 27 | while (left < right) { 28 | int mid = left + ((right - left) / 2).toInt(); 29 | if (arr[mid].compareTo(target) <= 0) { 30 | left = mid + 1; 31 | } else { 32 | right = mid; 33 | } 34 | } 35 | return left; 36 | } 37 | 38 | // > target ,返回最小值索引 39 | // == target,返回最大索引 40 | static int upper_ceil(List arr, T target) { 41 | int u = upper(arr, target); 42 | if (u - 1 >= 0 && arr[u - 1].compareTo(target) == 0) { 43 | return u - 1; 44 | } 45 | return u; 46 | } 47 | 48 | // >= target 的最小值索引 49 | static int lower_ceil(List data, T target) { 50 | int left = 0, right = data.length; 51 | // 在 data[l, r] 中寻找解 52 | while (left < right) { 53 | int mid = left + ((right - left) / 2).toInt(); 54 | if (data[mid].compareTo(target) < 0) 55 | left = mid + 1; 56 | else 57 | right = mid; 58 | } 59 | return left; 60 | } 61 | 62 | // < target 的最大值索引 63 | static int lower(List data, T target) { 64 | int left = -1, right = data.length - 1; 65 | // 在 data[l, r] 中寻找解 66 | while (left < right) { 67 | int mid = left + ((right - left + 1) / 2).toInt(); 68 | if (data[mid].compareTo(target) < 0) 69 | left = mid; 70 | else 71 | right = mid - 1; 72 | } 73 | return left; 74 | } 75 | } 76 | 77 | void main() { 78 | // int n = 1000; 79 | // List arr2 = ArrayGenerator.generateOrderedArray(n); 80 | // print(BinarySearch.search(arr2, 50)); 81 | var arr = [1, 1, 3, 3, 5, 5, 7, 7]; 82 | for (var i = 0; i <= 6; i++) { 83 | print(BinarySearch.lower(arr, i)); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /dart/09-Binary-Search-More/up/BinarySearchUp.dart: -------------------------------------------------------------------------------- 1 | import 'ArrayGenerator.dart'; 2 | 3 | /** 4 | * 二分搜索 5 | */ 6 | class BinarySearch{ 7 | 8 | BinarySearch(){} 9 | 10 | static int search(List data,T target){ 11 | 12 | int left = 0, right = data.length - 1; 13 | 14 | // 在 data[l, r] 的范围中查找 target 15 | while(left <= right){ 16 | int mid = left + ((right - left) / 2).toInt(); 17 | if(data[mid].compareTo(target) == 0) 18 | return mid; 19 | if(data[mid].compareTo(target) < 0) 20 | left = mid + 1; 21 | else 22 | right = mid - 1; 23 | } 24 | return -1; 25 | 26 | } 27 | // > target 的最小值索引 28 | static int upper(List arr,T target){ 29 | int left = 0,right = arr.length; 30 | while (left < right){ 31 | int mid = left +((right -left)/2).toInt(); 32 | if(arr[mid].compareTo(target)<=0){ 33 | left = mid +1; 34 | }else{ 35 | right = mid ; 36 | } 37 | } 38 | return left; 39 | } 40 | 41 | 42 | 43 | } 44 | 45 | void main(){ 46 | // int n = 1000; 47 | // List arr2 = ArrayGenerator.generateOrderedArray(n); 48 | // print(BinarySearch.search(arr2, 50)); 49 | var arr =[1,1,3,3,5,5,7,7]; 50 | for(var i = 0;i<=6;i++){ 51 | print(BinarySearch.upper(arr, i)); 52 | } 53 | } -------------------------------------------------------------------------------- /dart/09-Binary-Search/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i(List data,T target){ 11 | 12 | int left = 0, right = data.length - 1; 13 | 14 | // 在 data[l, r] 的范围中查找 target 15 | while(left <= right){ 16 | int mid = left + ((right - left) / 2).toInt(); 17 | if(data[mid].compareTo(target) == 0) 18 | return mid; 19 | if(data[mid].compareTo(target) < 0) 20 | left = mid + 1; 21 | else 22 | right = mid - 1; 23 | } 24 | return -1; 25 | 26 | } 27 | 28 | static int searchR(List data, T target){ 29 | return _searchBinaryR(data,0,data.length-1,target); 30 | } 31 | 32 | static int _searchBinaryR(List data,int left,int right,T target){ 33 | if(left>right){ 34 | return -1; 35 | } 36 | int mid = left + ((right - left) / 2).toInt(); 37 | if(data[mid].compareTo(target) == 0) 38 | return mid; 39 | if(data[mid].compareTo(target) < 0) 40 | return _searchBinaryR(data, mid + 1, right, target); 41 | return _searchBinaryR(data, left, mid - 1, target); 42 | } 43 | 44 | } 45 | 46 | void main(){ 47 | int n = 1000; 48 | List arr2 = ArrayGenerator.generateOrderedArray(n); 49 | print(BinarySearch.searchR(arr2, 100)); 50 | print(BinarySearch.search(arr2, 50)); 51 | } -------------------------------------------------------------------------------- /dart/10-Binary-Search-Tree/LinkedListQueue.dart: -------------------------------------------------------------------------------- 1 | import 'Queue.dart'; 2 | 3 | /** 4 | * 带尾结点的队列 5 | */ 6 | class LinkedListQueue implements Queue{ 7 | 8 | late _Node? _head; 9 | late _Node? _tail; 10 | late int _size; 11 | 12 | LinkedListQueue(){ 13 | _head = null; 14 | _tail = null; 15 | _size = 0; 16 | } 17 | 18 | @override 19 | dequeue() { 20 | if (isEmpty()) { 21 | throw Exception("Cannot dequeue from an empty queue"); 22 | } 23 | _Node retNode = _head!; 24 | _head = _head!.next; 25 | retNode.next = null; 26 | if(_head == null){ 27 | _tail =null; 28 | } 29 | _size --; 30 | return retNode.t; 31 | } 32 | 33 | @override 34 | void enqueue(e) { 35 | if(_tail == null){ 36 | _tail = _Node.wihtHead(e); 37 | _head = _tail; 38 | }else{ 39 | _tail!.next =_Node.wihtHead(e); 40 | _tail = _tail!.next; 41 | } 42 | _size++; 43 | } 44 | 45 | @override 46 | getFront() { 47 | if (isEmpty()) { 48 | throw Exception("Queue is empty"); 49 | } 50 | return _head!.t; 51 | } 52 | 53 | @override 54 | int getSize() { 55 | return _size; 56 | } 57 | 58 | @override 59 | bool isEmpty() { 60 | return _size == 0; 61 | } 62 | 63 | @override 64 | String toString() { 65 | StringBuffer res =new StringBuffer(); 66 | res.write("Queue: front "); 67 | for(_Node? cur = _head!.next ; cur != null ; cur = cur.next){ 68 | res.write(cur); 69 | res.write("->"); 70 | } 71 | res.write("NULL tail"); 72 | return res.toString(); 73 | } 74 | 75 | } 76 | 77 | //节点 78 | class _Node { 79 | _Node? next; 80 | 81 | T? t; 82 | 83 | _Node(); 84 | 85 | _Node.withAll(this.t, this.next); 86 | 87 | factory _Node.wihtHead(T t) { 88 | var result = new _Node.withAll(t, null); 89 | return result; 90 | } 91 | 92 | @override 93 | String toString() { 94 | return t.toString(); 95 | } 96 | } 97 | 98 | void main(){ 99 | LinkedListQueue queue = new LinkedListQueue(); 100 | for(int i = 0 ; i < 10 ; i ++){ 101 | queue.enqueue(i); 102 | print(queue); 103 | if(i % 3 ==2){ 104 | queue.dequeue(); 105 | print(queue); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /dart/10-Binary-Search-Tree/LinkedListStatck.dart: -------------------------------------------------------------------------------- 1 | import 'Stack.dart'; 2 | import 'LinkedList.dart'; 3 | 4 | class LinkedListStack implements Stack{ 5 | 6 | LinkedList? _linkedList; 7 | 8 | LinkedListStack(){ 9 | _linkedList =new LinkedList(); 10 | } 11 | 12 | @override 13 | int getSize() { 14 | return _linkedList!.getSize(); 15 | } 16 | 17 | @override 18 | bool isEmpty() { 19 | return _linkedList!.isEmpty(); 20 | } 21 | 22 | @override 23 | peek() { 24 | return _linkedList!.getFirst(); 25 | } 26 | 27 | @override 28 | pop() { 29 | _linkedList!.removeFirst(); 30 | } 31 | 32 | @override 33 | void push(e) { 34 | _linkedList!.addFirst(e); 35 | } 36 | 37 | @override 38 | String toString() { 39 | StringBuffer res = new StringBuffer(); 40 | res.write("Stack:top "); 41 | res.write(_linkedList); 42 | return res.toString(); 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /dart/10-Binary-Search-Tree/Main.dart: -------------------------------------------------------------------------------- 1 | import 'BST.dart'; 2 | void main(){ 3 | BST bst = new BST(); 4 | var list =[5,3,6,8,4,2]; 5 | for(var i = 0;i{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void enqueue(T e); 5 | T dequeue(); 6 | T getFront(); 7 | } -------------------------------------------------------------------------------- /dart/10-Binary-Search-Tree/Stack.dart: -------------------------------------------------------------------------------- 1 | abstract class Stack{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void push(T e); 5 | T pop(); 6 | T peek(); 7 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/BSTSet.dart: -------------------------------------------------------------------------------- 1 | import 'Set.dart'; 2 | import 'BST.dart'; 3 | 4 | /** 5 | * 二分搜索树集合 6 | */ 7 | class BSTSet> extends Set{ 8 | 9 | BST? bst; 10 | 11 | BSTSet(){ 12 | bst = BST(); 13 | } 14 | 15 | @override 16 | add(T e) { 17 | bst!.add(e); 18 | } 19 | 20 | @override 21 | bool contains(e) { 22 | return bst!.contains(e); 23 | } 24 | 25 | @override 26 | int? getSize() { 27 | return bst!.getSize(); 28 | } 29 | 30 | @override 31 | bool isEmpty() { 32 | return bst!.isEmpty(); 33 | } 34 | 35 | @override 36 | remove(e) { 37 | bst!.remove(e); 38 | } 39 | 40 | 41 | 42 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/FileOperator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | /** 5 | * 文件操作类 6 | */ 7 | class FileOperator{ 8 | 9 | static Future getFileString(String filename) async{ 10 | Stream> content = File(filename).openRead(); 11 | List lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList(); 12 | var words = []; 13 | for(int i = 0;i element == ""); 17 | return words; 18 | } 19 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/LinkedList.dart: -------------------------------------------------------------------------------- 1 | class LinkedList { 2 | _Node? _dummyHead; 3 | late int _size; 4 | 5 | LinkedList() { 6 | _dummyHead = new _Node.withEmpty(); 7 | _size = 0; 8 | } 9 | 10 | int getSize() { 11 | return _size; 12 | } 13 | 14 | bool isEmpty() { 15 | return _size == 0; 16 | } 17 | 18 | remove(int index){ 19 | if (index < 0 || index > _size) { 20 | throw Exception("Remove Failed,Illegal index"); 21 | } 22 | _Node? prev = _dummyHead; 23 | for(var i =0;i _size) { 46 | throw Exception("Add Failed,Illegal index"); 47 | } 48 | // if(index == 0){ 49 | // addFirst(t); 50 | // }else{ 51 | _Node? prev = _dummyHead; 52 | for (var i = 0; i < index; i++) { 53 | prev = prev?.next; 54 | } 55 | _Node _node = new _Node.wihtHead(t); 56 | _node.next = prev?.next; 57 | prev?.next = _node; 58 | _size++; 59 | // } 60 | } 61 | 62 | addLast(T t) { 63 | add(_size, t); 64 | } 65 | 66 | addFirst(T t) { 67 | // _Node _node =new _Node.head(t); 68 | // _node.next = _head; 69 | // _head = _node; 70 | add(0, t); 71 | } 72 | 73 | //获取链表第index位置的元素 74 | T get(int index){ 75 | if (index < 0 || index > _size) { 76 | throw Exception("Get Failed,Illegal index"); 77 | } 78 | _Node? cur = _dummyHead!.next; 79 | for(var i=0;i _size) { 93 | throw Exception("Set Failed,Illegal index"); 94 | } 95 | _Node? cur = _dummyHead!.next; 96 | for(var i =0;i"); 119 | } 120 | res.write("NULL"); 121 | return res.toString(); 122 | } 123 | } 124 | //节点 125 | class _Node { 126 | _Node? next; 127 | 128 | T? t; 129 | 130 | _Node.withEmpty(); 131 | 132 | _Node.withAll(this.t, this.next); 133 | 134 | factory _Node.wihtHead(T t) { 135 | var result = new _Node.withAll(t, null); 136 | return result; 137 | } 138 | 139 | @override 140 | String toString() { 141 | return t.toString(); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /dart/11-Set-And-Map/LinkedListMap.dart: -------------------------------------------------------------------------------- 1 | import 'Map.dart'; 2 | 3 | /** 4 | * 链表映射 5 | */ 6 | class LinkedListMap extends Map{ 7 | 8 | _Node? dummyHead; 9 | int? size; 10 | 11 | @override 12 | add(key, value) { 13 | _Node? node = _getNode(key); 14 | if(node == null){ 15 | dummyHead!.next = _Node(key, value, dummyHead!.next); 16 | size = size! + 1; 17 | } 18 | else{ 19 | node.value = value; 20 | } 21 | } 22 | 23 | LinkedListMap(){ 24 | dummyHead =_Node.withEmty(); 25 | size = 0; 26 | } 27 | 28 | @override 29 | bool contains(key) { 30 | return _getNode(key) != null; 31 | } 32 | 33 | @override 34 | get(key) { 35 | _Node? node = _getNode(key); 36 | return node == null ? null : node.value; 37 | } 38 | 39 | @override 40 | int? getSize() { 41 | return size; 42 | } 43 | 44 | @override 45 | bool isEmpty() { 46 | return size == 0; 47 | } 48 | 49 | @override 50 | V? remove(K key) { 51 | _Node prev = dummyHead!; 52 | while(prev.next != null){ 53 | if(prev.next!.key.equals(key)) 54 | break; 55 | prev = prev.next!; 56 | } 57 | 58 | if(prev.next != null){ 59 | _Node delNode = prev.next!; 60 | prev.next = delNode.next; 61 | delNode.next = null; 62 | size = size! -1; 63 | return delNode.value; 64 | } 65 | 66 | return null; 67 | } 68 | 69 | @override 70 | set(K key, newValue) { 71 | _Node? node = _getNode(key); 72 | if(node == null){ 73 | throw new Exception("${key} doesn't exist!"); 74 | } 75 | node.value = newValue; 76 | } 77 | 78 | _Node? _getNode(K key){ 79 | _Node? cur = dummyHead!.next; 80 | while(cur != null){ 81 | if(cur.key.equals(key)) 82 | return cur; 83 | cur = cur.next; 84 | } 85 | return null; 86 | } 87 | 88 | } 89 | class _Node{ 90 | K? key; 91 | V? value; 92 | _Node? next; 93 | 94 | _Node(this.key, this.value, this.next); 95 | 96 | _Node.withEmptyHead(K key, V value){ 97 | _Node(key, value, null); 98 | } 99 | 100 | _Node.withEmty(){ 101 | _Node(null, null, null); 102 | } 103 | @override 104 | String toString() { 105 | StringBuffer res =new StringBuffer(); 106 | res.write("${key.toString()} : ${value.toString()}"); 107 | return res.toString(); 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /dart/11-Set-And-Map/LinkedListQueue.dart: -------------------------------------------------------------------------------- 1 | import 'Queue.dart'; 2 | 3 | /** 4 | * 带尾结点的队列 5 | */ 6 | class LinkedListQueue implements Queue{ 7 | 8 | late _Node? _head; 9 | late _Node? _tail; 10 | late int _size; 11 | 12 | LinkedListQueue(){ 13 | _head = null; 14 | _tail = null; 15 | _size = 0; 16 | } 17 | 18 | @override 19 | dequeue() { 20 | if (isEmpty()) { 21 | throw Exception("Cannot dequeue from an empty queue"); 22 | } 23 | _Node retNode = _head!; 24 | _head = _head!.next; 25 | retNode.next = null; 26 | if(_head == null){ 27 | _tail =null; 28 | } 29 | _size --; 30 | return retNode.t; 31 | } 32 | 33 | @override 34 | void enqueue(e) { 35 | if(_tail == null){ 36 | _tail = _Node.wihtHead(e); 37 | _head = _tail; 38 | }else{ 39 | _tail!.next =_Node.wihtHead(e); 40 | _tail = _tail!.next; 41 | } 42 | _size++; 43 | } 44 | 45 | @override 46 | getFront() { 47 | if (isEmpty()) { 48 | throw Exception("Queue is empty"); 49 | } 50 | return _head!.t; 51 | } 52 | 53 | @override 54 | int getSize() { 55 | return _size; 56 | } 57 | 58 | @override 59 | bool isEmpty() { 60 | return _size == 0; 61 | } 62 | 63 | @override 64 | String toString() { 65 | StringBuffer res =new StringBuffer(); 66 | res.write("Queue: front "); 67 | for(_Node? cur = _head!.next ; cur != null ; cur = cur.next){ 68 | res.write(cur); 69 | res.write("->"); 70 | } 71 | res.write("NULL tail"); 72 | return res.toString(); 73 | } 74 | 75 | } 76 | 77 | //节点 78 | class _Node { 79 | _Node? next; 80 | 81 | T? t; 82 | 83 | _Node(); 84 | 85 | _Node.withAll(this.t, this.next); 86 | 87 | factory _Node.wihtHead(T t) { 88 | var result = new _Node.withAll(t, null); 89 | return result; 90 | } 91 | 92 | @override 93 | String toString() { 94 | return t.toString(); 95 | } 96 | } 97 | 98 | void main(){ 99 | LinkedListQueue queue = new LinkedListQueue(); 100 | for(int i = 0 ; i < 10 ; i ++){ 101 | queue.enqueue(i); 102 | print(queue); 103 | if(i % 3 ==2){ 104 | queue.dequeue(); 105 | print(queue); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/LinkedListStatck.dart: -------------------------------------------------------------------------------- 1 | import 'Stack.dart'; 2 | import 'LinkedList.dart'; 3 | 4 | /** 5 | * 链表栈 6 | */ 7 | class LinkedListStack implements Stack{ 8 | 9 | LinkedList? _linkedList; 10 | 11 | LinkedListStack(){ 12 | _linkedList =new LinkedList(); 13 | } 14 | 15 | @override 16 | int getSize() { 17 | return _linkedList!.getSize(); 18 | } 19 | 20 | @override 21 | bool isEmpty() { 22 | return _linkedList!.isEmpty(); 23 | } 24 | 25 | @override 26 | peek() { 27 | return _linkedList!.getFirst(); 28 | } 29 | 30 | @override 31 | pop() { 32 | _linkedList!.removeFirst(); 33 | } 34 | 35 | @override 36 | void push(e) { 37 | _linkedList!.addFirst(e); 38 | } 39 | 40 | @override 41 | String toString() { 42 | StringBuffer res = new StringBuffer(); 43 | res.write("Stack:top "); 44 | res.write(_linkedList); 45 | return res.toString(); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/Main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | import 'FileOperator.dart'; 4 | import 'BSTSet.dart'; 5 | import 'BST.dart'; 6 | 7 | void main() async{ 8 | 9 | List result = await FileOperator.getFileString('text2.txt'); 10 | // print(result); 11 | print("总数量:${result.length}"); 12 | BSTSet bstSet1 =new BSTSet(); 13 | for (String word in result){ 14 | bstSet1.add(word); 15 | } 16 | 17 | print("Total different words: ${bstSet1.getSize()}"); 18 | 19 | 20 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/Map.dart: -------------------------------------------------------------------------------- 1 | abstract class Map{ 2 | add(K key, V value); 3 | V? remove(K key); 4 | bool contains(K key); 5 | V get(K key); 6 | set(K key, V newValue); 7 | int? getSize(); 8 | bool isEmpty(); 9 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/Queue.dart: -------------------------------------------------------------------------------- 1 | abstract class Queue{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void enqueue(T e); 5 | T dequeue(); 6 | T getFront(); 7 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/Set.dart: -------------------------------------------------------------------------------- 1 | abstract class Set{ 2 | 3 | add(T e); 4 | bool contains(T e); 5 | remove(T e); 6 | int? getSize(); 7 | bool isEmpty(); 8 | } -------------------------------------------------------------------------------- /dart/11-Set-And-Map/Stack.dart: -------------------------------------------------------------------------------- 1 | abstract class Stack{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void push(T e); 5 | T pop(); 6 | T peek(); 7 | } -------------------------------------------------------------------------------- /dart/12-Heap/HeapSort.dart: -------------------------------------------------------------------------------- 1 | import 'MaxHeap.dart'; 2 | 3 | /** 4 | * 堆排序 5 | * 以及堆排序优化 6 | */ 7 | class HeapSort { 8 | HeapSort() {} 9 | 10 | static sort>(List data) { 11 | MaxHeap maxHeap = MaxHeap.withCapacity(10); 12 | for (E e in data) { 13 | maxHeap.add(e); 14 | }; 15 | 16 | for (int i = data.length - 1; i >= 0; i--) { 17 | data[i] = maxHeap.extractMax(); 18 | } 19 | } 20 | 21 | static sort2>(List data) { 22 | if (data.length <= 1) return; 23 | 24 | for (int i = (data.length - 2) / 2 as int; i >= 0; i--){ 25 | _siftDown(data, i, data.length); 26 | } 27 | for (int i = data.length - 1; i >= 0; i--) { 28 | _swap(data, 0, i); 29 | _siftDown(data, 0, i); 30 | } 31 | } 32 | 33 | // 对 data[0, n) 所形成的最大堆中,索引 k 的元素,执行 siftDown 34 | static _siftDown(List? data, int k, int n) { 35 | while (2 * k + 1 < n) { 36 | int j = 2 * k + 1; // 在此轮循环中,data[k]和data[j]交换位置 37 | if (j + 1 < n && data![j + 1].compareTo(data[j]) > 0) { 38 | j++; 39 | } 40 | // data[j] 是 leftChild 和 rightChild 中的最大值 41 | if (data![k].compareTo(data[j]) >= 0) { 42 | break; 43 | } 44 | _swap(data, k, j); 45 | k = j; 46 | } 47 | } 48 | 49 | static _swap(List arr, int i, int j) { 50 | E t = arr[i]; 51 | arr[i] = arr[j]; 52 | arr[j] = t; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /dart/12-Heap/Main.dart: -------------------------------------------------------------------------------- 1 | import 'MaxHeap.dart'; 2 | import 'dart:math'; 3 | void main(){ 4 | 5 | int n = 100; 6 | 7 | MaxHeap maxHeap = new MaxHeap.withEmpty(); 8 | Random random = new Random(); 9 | 10 | for(int i = 0 ; i < n ; i ++){ 11 | maxHeap.add(random.nextInt(1<<32)); 12 | } 13 | print(maxHeap); 14 | List arr = List.filled(n, num, growable: true); 15 | for(int i = 0 ; i < n ; i ++){ 16 | arr[i] = maxHeap.extractMax(); 17 | } 18 | print(arr); 19 | for(int i = 1 ; i < n ; i ++){ 20 | if(arr[i-1] < arr[i]){ 21 | throw new Exception("Error"); 22 | } 23 | } 24 | 25 | print("Test MaxHeap completed"); 26 | 27 | 28 | 29 | } -------------------------------------------------------------------------------- /dart/12-Heap/MaxHeap.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 最大堆 3 | */ 4 | class MaxHeap>{ 5 | 6 | List? _data ; 7 | 8 | MaxHeap.withCapacity(int capacity){ 9 | _data = List.filled(capacity, E, growable: true); 10 | } 11 | 12 | MaxHeap.withEmpty(){ 13 | _data = List.empty(growable: true); 14 | } 15 | 16 | // 返回堆中的元素个数 17 | int? size(){ 18 | return _data!.length; 19 | } 20 | 21 | // 返回一个布尔值, 表示堆中是否为空 22 | bool isEmpty(){ 23 | return _data!.isEmpty; 24 | } 25 | 26 | int _parent(int index){ 27 | if(index == 0){ 28 | throw Exception("index-0 doesn't have parent."); 29 | } 30 | return ((index - 1) / 2).toInt(); 31 | } 32 | 33 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引 34 | int _leftChild(int index){ 35 | return index * 2 + 1; 36 | } 37 | 38 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引 39 | int _rightChild(int index){ 40 | return index * 2 + 2; 41 | } 42 | 43 | // 向堆中添加元素 44 | add(E e){ 45 | _data!.add(e); 46 | siftUp(_data!.length - 1); 47 | } 48 | 49 | siftUp(int k){ 50 | while(k > 0 && _data![_parent(k)].compareTo(_data![k]) < 0 ){ 51 | _swap(k, _parent(k)); 52 | k = _parent(k); 53 | } 54 | } 55 | 56 | // 看堆中的最大元素 57 | E findMax(){ 58 | if(_data!.length == 0) 59 | throw new Exception("Can not findMax when heap is empty."); 60 | return _data![0]; 61 | } 62 | 63 | // 取出堆中最大元素 64 | E extractMax(){ 65 | E ret = findMax(); 66 | _swap(0, _data!.length - 1); 67 | _data!.removeLast(); 68 | _siftDown(0); 69 | 70 | return ret; 71 | } 72 | 73 | _siftDown(int k){ 74 | while(_leftChild(k) < _data!.length){ 75 | int j = _leftChild(k); // 在此轮循环中,_data[k]和data[j]交换位置 76 | if( j + 1 < _data!.length && 77 | _data![j+1].compareTo(_data![j]) > 0 ) 78 | j ++; 79 | // _data[j] 是 leftChild 和 rightChild 中的最大值 80 | if(_data![k].compareTo(_data![j]) >= 0 ) 81 | break; 82 | _swap(k, j); 83 | k = j; 84 | } 85 | } 86 | 87 | // 取出堆中的最大元素,并且替换成元素e 88 | E replace(E e){ 89 | 90 | E ret = findMax(); 91 | _data![0] =e;; 92 | _siftDown(0); 93 | return ret; 94 | } 95 | 96 | _swap(int i, int j){ 97 | if(i < 0 || i >= _data!.length || j < 0 || j >= _data!.length) 98 | throw new Exception("Index is illegal."); 99 | 100 | E t = _data![i]; 101 | _data![i] = _data![j]; 102 | _data![j] = t; 103 | } 104 | 105 | } -------------------------------------------------------------------------------- /dart/12-Heap/MinHeap.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 最小堆 3 | */ 4 | class MinHeap> { 5 | List? _data; 6 | 7 | MinHeap.withCapacity(int capacity) { 8 | _data = List.filled(capacity, E, growable: true); 9 | } 10 | 11 | MinHeap.withEmpty() { 12 | _data = List.empty(growable: true); 13 | } 14 | 15 | // 返回堆中的元素个数 16 | int? size() { 17 | return _data!.length; 18 | } 19 | 20 | // 返回一个布尔值, 表示堆中是否为空 21 | bool isEmpty() { 22 | return _data!.isEmpty; 23 | } 24 | 25 | int _parent(int index) { 26 | if (index == 0) { 27 | throw Exception("index-0 doesn't have parent."); 28 | } 29 | return ((index - 1) / 2).toInt(); 30 | } 31 | 32 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引 33 | int _leftChild(int index) { 34 | return index * 2 + 1; 35 | } 36 | 37 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引 38 | int _rightChild(int index) { 39 | return index * 2 + 2; 40 | } 41 | 42 | // 向堆中添加元素 43 | add(E e) { 44 | _data!.add(e); 45 | siftUp(_data!.length - 1); 46 | } 47 | 48 | siftUp(int k) { 49 | while (k > 0 && _data![_parent(k)].compareTo(_data![k]) > 0) { 50 | _swap(k, _parent(k)); 51 | k = _parent(k); 52 | } 53 | } 54 | 55 | // 看堆中的最大元素 56 | E findMin() { 57 | if (_data!.length == 0) 58 | throw new Exception("Can not findMax when heap is empty."); 59 | return _data![0]; 60 | } 61 | 62 | // 取出堆中最大元素 63 | E extractMax() { 64 | E ret = findMin(); 65 | _swap(0, _data!.length - 1); 66 | _data!.removeLast(); 67 | _siftDown(0); 68 | 69 | return ret; 70 | } 71 | 72 | _siftDown(int k) { 73 | while (_leftChild(k) < _data!.length) { 74 | int j = _leftChild(k); // 在此轮循环中,_data[k]和data[j]交换位置 75 | if (j + 1 < _data!.length && _data![j + 1].compareTo(_data![j]) < 0) { 76 | j++; 77 | } 78 | // _data[j] 是 leftChild 和 rightChild 中的最大值 79 | if (_data![k].compareTo(_data![j]) <= 0) { 80 | break; 81 | } 82 | _swap(k, j); 83 | k = j; 84 | } 85 | } 86 | 87 | // 取出堆中的最大元素,并且替换成元素e 88 | E replace(E e) { 89 | E ret = findMin(); 90 | _data![0] = e; 91 | ; 92 | _siftDown(0); 93 | return ret; 94 | } 95 | 96 | _swap(int i, int j) { 97 | if (i < 0 || i >= _data!.length || j < 0 || j >= _data!.length) 98 | throw new Exception("Index is illegal."); 99 | 100 | E t = _data![i]; 101 | _data![i] = _data![j]; 102 | _data![j] = t; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /dart/12-Heap/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | //import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/13-Priority-Queue/MaxHeap.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 最大堆 3 | */ 4 | class MaxHeap>{ 5 | 6 | List? _data ; 7 | 8 | MaxHeap.withCapacity(int capacity){ 9 | _data = List.filled(capacity, E, growable: true); 10 | } 11 | 12 | MaxHeap.withEmpty(){ 13 | _data = List.empty(growable: true); 14 | } 15 | 16 | // 返回堆中的元素个数 17 | int? size(){ 18 | return _data!.length; 19 | } 20 | 21 | // 返回一个布尔值, 表示堆中是否为空 22 | bool isEmpty(){ 23 | return _data!.isEmpty; 24 | } 25 | 26 | int _parent(int index){ 27 | if(index == 0){ 28 | throw Exception("index-0 doesn't have parent."); 29 | } 30 | return ((index - 1) / 2).toInt(); 31 | } 32 | 33 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引 34 | int _leftChild(int index){ 35 | return index * 2 + 1; 36 | } 37 | 38 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引 39 | int _rightChild(int index){ 40 | return index * 2 + 2; 41 | } 42 | 43 | // 向堆中添加元素 44 | add(E e){ 45 | _data!.add(e); 46 | siftUp(_data!.length - 1); 47 | } 48 | 49 | siftUp(int k){ 50 | while(k > 0 && _data![_parent(k)].compareTo(_data![k]) < 0 ){ 51 | _swap(k, _parent(k)); 52 | k = _parent(k); 53 | } 54 | } 55 | 56 | // 看堆中的最大元素 57 | E findMax(){ 58 | if(_data!.length == 0) 59 | throw new Exception("Can not findMax when heap is empty."); 60 | return _data![0]; 61 | } 62 | 63 | // 取出堆中最大元素 64 | E extractMax(){ 65 | E ret = findMax(); 66 | _swap(0, _data!.length - 1); 67 | _data!.removeLast(); 68 | _siftDown(0); 69 | 70 | return ret; 71 | } 72 | 73 | _siftDown(int k){ 74 | while(_leftChild(k) < _data!.length){ 75 | int j = _leftChild(k); // 在此轮循环中,_data[k]和data[j]交换位置 76 | if( j + 1 < _data!.length && 77 | _data![j+1].compareTo(_data![j]) > 0 ) 78 | j ++; 79 | // _data[j] 是 leftChild 和 rightChild 中的最大值 80 | if(_data![k].compareTo(_data![j]) >= 0 ) 81 | break; 82 | _swap(k, j); 83 | k = j; 84 | } 85 | } 86 | 87 | // 取出堆中的最大元素,并且替换成元素e 88 | E replace(E e){ 89 | 90 | E ret = findMax(); 91 | _data![0] =e;; 92 | _siftDown(0); 93 | return ret; 94 | } 95 | 96 | _swap(int i, int j){ 97 | if(i < 0 || i >= _data!.length || j < 0 || j >= _data!.length) 98 | throw new Exception("Index is illegal."); 99 | 100 | E t = _data![i]; 101 | _data![i] = _data![j]; 102 | _data![j] = t; 103 | } 104 | 105 | } -------------------------------------------------------------------------------- /dart/13-Priority-Queue/PriorityQueue.dart: -------------------------------------------------------------------------------- 1 | import 'Queue.dart'; 2 | import 'MaxHeap.dart'; 3 | 4 | class PriorityQueue> implements Queue { 5 | 6 | MaxHeap? _maxHeap; 7 | 8 | PriorityQueue(){ 9 | _maxHeap = new MaxHeap.withEmpty(); 10 | } 11 | 12 | @override 13 | int? getSize(){ 14 | return _maxHeap!.size(); 15 | } 16 | 17 | @override 18 | bool isEmpty(){ 19 | return _maxHeap!.isEmpty(); 20 | } 21 | 22 | @override 23 | E getFront(){ 24 | return _maxHeap!.findMax(); 25 | } 26 | 27 | @override 28 | enqueue(E e){ 29 | _maxHeap!.add(e); 30 | } 31 | 32 | @override 33 | dequeue(){ 34 | return _maxHeap!.extractMax(); 35 | } 36 | } -------------------------------------------------------------------------------- /dart/13-Priority-Queue/Queue.dart: -------------------------------------------------------------------------------- 1 | abstract class Queue{ 2 | int? getSize(); 3 | bool isEmpty(); 4 | void enqueue(T e); 5 | T dequeue(); 6 | T getFront(); 7 | } -------------------------------------------------------------------------------- /dart/14-Bubble-Sort/BubblSort.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 冒泡排序,每轮选出最大的值,放到最后 3 | * 处理相邻的逆序对 4 | */ 5 | class BubblSort { 6 | static sort(List? data) { 7 | for (int i = 0; i + 1 < data!.length; i++) { 8 | // arr[n - i, n) 已排好序 9 | // 通过冒泡在 arr[n - i - 1] 位置放上合适的元素 10 | for (int j = 0; j < data.length - i - 1; j++) { 11 | if (data[j].compareTo(data[j + 1]) > 0) { 12 | _swap(data, j, j + 1); 13 | } 14 | } 15 | } 16 | } 17 | 18 | static sort2(List? data) { 19 | for (int i = 0; i + 1 < data!.length; i++) { 20 | // arr[n - i, n) 已排好序 21 | // 通过冒泡在 arr[n - i - 1] 位置放上合适的元素 22 | bool isSwapped = false; 23 | for (int j = 0; j < data.length - i - 1; j++) { 24 | if (data[j].compareTo(data[j + 1]) > 0) { 25 | _swap(data, j, j + 1); 26 | isSwapped = true; 27 | } 28 | } 29 | if (!isSwapped) { 30 | break; 31 | } 32 | } 33 | } 34 | 35 | static sort3(List? data) { 36 | for (int i = 0; i + 1 < data!.length;) { 37 | // arr[n - i, n) 已排好序 38 | // 通过冒泡在 arr[n - i - 1] 位置放上合适的元素 39 | int lastSwappedIndex = 0; 40 | for (int j = 0; j < data.length - i - 1; j++) { 41 | if (data[j].compareTo(data[j + 1]) > 0) { 42 | _swap(data, j, j + 1); 43 | lastSwappedIndex = j + 1; 44 | } 45 | } 46 | i = data.length - lastSwappedIndex; 47 | } 48 | } 49 | 50 | static _swap(List? arr, int i, int j) { 51 | var t = arr![i]; 52 | arr[i] = arr[j]; 53 | arr[j] = t; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dart/14-Bubble-Sort/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | //import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | // ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/15-Shell-Sort/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i= 1) { 12 | for (int start = 0; start < h; start++) { 13 | // 对 data[start, start + h, start + 2h, start + 3h ...], 进行插入排序 14 | for (int i = start + h; i < data.length; i += h) { 15 | var t = data[i]; 16 | int j; 17 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) 18 | data[j] = data[j - h]; 19 | data[j] = t; 20 | } 21 | } 22 | h = (h / 2).toInt(); 23 | } 24 | } 25 | 26 | //希尔排序优化 27 | static sort2(List? data) { 28 | int h = (data!.length / 2).toInt(); 29 | while (h >= 1) { 30 | for (int i = h; i < data.length; i++) { 31 | var t = data[i]; 32 | int j; 33 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) { 34 | data[j] = data[j - h]; 35 | } 36 | data[j] = t; 37 | } 38 | h = (h / 2).toInt(); 39 | } 40 | } 41 | 42 | //希尔排序设定步长序列 43 | static sort3(List? data) { 44 | int h = 1; 45 | while (h < data!.length) { 46 | h = 3 * h + 1; 47 | } 48 | // 1, 4, 13, 40 ... 49 | while (h >= 1) { 50 | for (int i = h; i < data.length; i++) { 51 | var t = data[i]; 52 | int j; 53 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) { 54 | data[j] = data[j - h]; 55 | } 56 | data[j] = t; 57 | } 58 | h = (h / 3).toInt(); 59 | } 60 | } 61 | } 62 | 63 | void main() { 64 | int n = 100000; 65 | List arr = ArrayGenerator.generateRandomArray(n, n); 66 | 67 | SortingHelper.sortTest("ShellSort", arr); 68 | } 69 | -------------------------------------------------------------------------------- /dart/15-Shell-Sort/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/16-Segment-Tree/Main.dart: -------------------------------------------------------------------------------- 1 | import 'Segment.dart'; 2 | import 'Merger.dart'; 3 | 4 | class NewMerger implements Merger{ 5 | @override 6 | merge(a, b) { 7 | return a + b ; 8 | } 9 | 10 | } 11 | 12 | void main(){ 13 | List nums = [-2, 0, 3, -5, 2, -1]; 14 | // NewMerger selfMerger = NewMerger(); 15 | // SegmentTree segTree = SegmentTree(nums, selfMerger); 16 | SegmentTree segmentTreeSec = SegmentTree(nums, new NewMerger()); 17 | print(segmentTreeSec.toString()); 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /dart/16-Segment-Tree/Merger.dart: -------------------------------------------------------------------------------- 1 | abstract class Merger{ 2 | E merge(E a, E b); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /dart/17-Trie/FileOperator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | /** 5 | * 文件操作类 6 | */ 7 | class FileOperator{ 8 | 9 | static Future getFileString(String filename) async{ 10 | Stream> content = File(filename).openRead(); 11 | List lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList(); 12 | var words = []; 13 | for(int i = 0;i element == ""); 17 | return words; 18 | } 19 | } -------------------------------------------------------------------------------- /dart/17-Trie/Main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'Trie.dart'; 5 | import 'FileOperator.dart'; 6 | void main() async{ 7 | 8 | List result = await FileOperator.getFileString('text2.txt'); 9 | // print(result); 10 | print("总数量:${result.length}"); 11 | var now = new DateTime.now(); 12 | num startTime = now.millisecondsSinceEpoch; 13 | 14 | Trie trie = new Trie(); 15 | for(String word in result) 16 | trie.add(word); 17 | 18 | for(String word in result) 19 | trie.contains(word); 20 | 21 | var endNow = new DateTime.now(); 22 | num endTime = endNow.millisecondsSinceEpoch; 23 | print("开始时间:$startTime : 结束时间:$endTime"); 24 | double time = (endTime - startTime) / 1000.0; 25 | 26 | print("Total different words: ${trie.getSize()}"); 27 | print("Trie: $time s"); 28 | 29 | } -------------------------------------------------------------------------------- /dart/17-Trie/Trie.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | class Trie { 4 | _Node? _root; 5 | 6 | int? _size; 7 | 8 | Trie() { 9 | _root = _Node(); 10 | _size = 0; 11 | } 12 | 13 | int? getSize() { 14 | return _size; 15 | } 16 | 17 | add(String? word) { 18 | _Node? cur = _root; 19 | for (int i = 0; i < word!.length; i++) { 20 | String c = word[i]; 21 | if (cur!.next![c] == null) { 22 | cur.next!.putIfAbsent(c, () => _Node()); 23 | } 24 | cur = cur.next![c]; 25 | } 26 | if (!(cur!.isWord!)) { 27 | cur.isWord = true; 28 | _size = _size! + 1; 29 | } 30 | } 31 | 32 | // 查询单词word是否在Trie中 33 | bool contains(String word) { 34 | _Node? cur = _root; 35 | for (int i = 0; i < word.length; i++) { 36 | String c = word[i]; 37 | if (cur!.next![c] == null) { 38 | return false; 39 | } 40 | cur = cur.next![c]; 41 | } 42 | return cur!.isWord!; 43 | } 44 | 45 | // 查询是否在Trie中有单词以prefix为前缀 46 | bool isPrefix(String prefix){ 47 | _Node? cur = _root; 48 | for(int i = 0 ; i < prefix.length ; i ++){ 49 | String c = prefix[i]; 50 | if(cur!.next![c] == null){ 51 | return false; 52 | } 53 | cur = cur.next![c]; 54 | } 55 | return true; 56 | } 57 | } 58 | 59 | class _Node { 60 | bool? isWord; 61 | 62 | SplayTreeMap? next; 63 | 64 | _Node.isWord(bool isWord) { 65 | this.isWord = isWord; 66 | next = new SplayTreeMap(); 67 | } 68 | 69 | factory _Node() { 70 | return _Node.isWord(false); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dart/18-Union-Find/Main.dart: -------------------------------------------------------------------------------- 1 | import 'UnionFind1.dart'; 2 | import 'UnionFind2.dart'; 3 | import 'UnionFind3.dart'; 4 | import 'UnionFind4.dart'; 5 | import 'UnionFind5.dart'; 6 | import 'UnionFind6.dart'; 7 | import 'dart:math'; 8 | import 'UF.dart'; 9 | 10 | double testUF(UF uf, int m){ 11 | 12 | int? size = uf.getSize(); 13 | Random random = new Random(); 14 | 15 | var now = new DateTime.now(); 16 | num startTime = now.millisecondsSinceEpoch; 17 | 18 | 19 | for(int i = 0 ; i < m ; i ++){ 20 | int a = random.nextInt(size!); 21 | int b = random.nextInt(size); 22 | uf.unionElements(a, b); 23 | } 24 | 25 | for(int i = 0 ; i < m ; i ++){ 26 | int a = random.nextInt(size!); 27 | int b = random.nextInt(size); 28 | uf.isConnected(a, b); 29 | } 30 | 31 | var endNow = new DateTime.now(); 32 | num endTime = endNow.millisecondsSinceEpoch; 33 | 34 | double time = (endTime - startTime) / 1000.0; 35 | return time; 36 | } 37 | 38 | void main(){ 39 | int size = 10000000; 40 | int m = 10000000; 41 | 42 | UnionFind3 uf3 = new UnionFind3(size); 43 | print("UnionFind3 : ${testUF(uf3, m)} s"); 44 | 45 | UnionFind4 uf4 = new UnionFind4(size); 46 | print("UnionFind4 : ${testUF(uf4, m)} s"); 47 | 48 | UnionFind5 uf5 = new UnionFind5(size); 49 | print("UnionFind5 : ${testUF(uf5, m)} s"); 50 | 51 | UnionFind6 uf6 = new UnionFind6(size); 52 | print("UnionFind6 : ${testUF(uf6, m)} s"); 53 | 54 | } -------------------------------------------------------------------------------- /dart/18-Union-Find/UF.dart: -------------------------------------------------------------------------------- 1 | abstract class UF { 2 | int? getSize(); 3 | bool isConnected(int p, int q); 4 | void unionElements(int p, int q); 5 | 6 | } -------------------------------------------------------------------------------- /dart/18-Union-Find/UnionFind1.dart: -------------------------------------------------------------------------------- 1 | import 'UF.dart'; 2 | 3 | /** 4 | * 第一版并查集 5 | */ 6 | class UnionFind1 extends UF { 7 | 8 | List? id; 9 | 10 | UnionFind1(int size) { 11 | 12 | id = List.filled(size, num , growable: false); 13 | // 初始化, 每一个id[i]指向自己, 没有合并的元素 14 | for (var i = 0; i < size; i++){ 15 | id![i] = i; 16 | } 17 | } 18 | 19 | @override 20 | int? getSize(){ 21 | return id!.length; 22 | } 23 | 24 | // 查找元素p所对应的集合编号 25 | // O(1)复杂度 26 | int find(int p) { 27 | if(p < 0 || p >= id!.length){ 28 | throw new Exception("p is out of bound."); 29 | } 30 | return id![p]; 31 | } 32 | 33 | // 查看元素p和元素q是否所属一个集合 34 | // O(1)复杂度 35 | @override 36 | bool isConnected(int p, int q) { 37 | return find(p) == find(q); 38 | } 39 | 40 | // 合并元素p和元素q所属的集合 41 | // O(n) 复杂度 42 | @override 43 | unionElements(int p, int q) { 44 | 45 | int pID = find(p); 46 | int qID = find(q); 47 | 48 | if (pID == qID){ 49 | return; 50 | } 51 | // 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并 52 | for (var i = 0; i < id!.length; i++){ 53 | if (id![i] == pID){ 54 | id![i] = qID; 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /dart/18-Union-Find/UnionFind2.dart: -------------------------------------------------------------------------------- 1 | import 'UF.dart'; 2 | /** 3 | * 第二版并查集 4 | */ 5 | class UnionFind2 extends UF { 6 | 7 | // 使用一个数组构建一棵指向父节点的树 8 | // parent[i]表示第一个元素所指向的父节点 9 | List? parent; 10 | 11 | // 构造函数 12 | UnionFind2(int size){ 13 | 14 | parent = List.filled(size, num,growable: false); 15 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 16 | for( var i = 0 ; i < size ; i ++ ){ 17 | parent![i] = i; 18 | } 19 | } 20 | 21 | @override 22 | int? getSize(){ 23 | return parent!.length; 24 | } 25 | 26 | // 查找过程, 查找元素p所对应的集合编号 27 | // O(h)复杂度, h为树的高度 28 | int find(int p){ 29 | if(p < 0 || p >= parent!.length) 30 | throw new Exception("p is out of bound."); 31 | 32 | // 不断去查询自己的父亲节点, 直到到达根节点 33 | // 根节点的特点: parent[p] == p 34 | while(p != parent![p]){ 35 | p = parent![p]; 36 | } 37 | return p; 38 | } 39 | 40 | // 查看元素p和元素q是否所属一个集合 41 | // O(h)复杂度, h为树的高度 42 | @override 43 | bool isConnected( int p , int q ){ 44 | return find(p) == find(q); 45 | } 46 | 47 | // 合并元素p和元素q所属的集合 48 | // O(h)复杂度, h为树的高度 49 | @override 50 | unionElements(int p, int q){ 51 | 52 | int pRoot = find(p); 53 | int qRoot = find(q); 54 | 55 | if( pRoot == qRoot ) { 56 | return; 57 | } 58 | parent![pRoot] = qRoot; 59 | } 60 | } -------------------------------------------------------------------------------- /dart/18-Union-Find/UnionFind3.dart: -------------------------------------------------------------------------------- 1 | import 'UF.dart'; 2 | 3 | /** 4 | * 第三版 并查集 5 | */ 6 | class UnionFind3 extends UF { 7 | List? parent; // parent[i]表示第一个元素所指向的父节点 8 | List? sz; // sz[i]表示以i为根的集合中元素个数 9 | 10 | // 构造函数 11 | UnionFind3(int size) { 12 | parent = List.filled(size, num, growable: false); 13 | sz = List.filled(size, num, growable: false); 14 | 15 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 16 | for (int i = 0; i < size; i++) { 17 | parent![i] = i; 18 | sz![i] = 1; 19 | } 20 | } 21 | 22 | @override 23 | int? getSize() { 24 | return parent!.length; 25 | } 26 | 27 | // 查找过程, 查找元素p所对应的集合编号 28 | // O(h)复杂度, h为树的高度 29 | int find(int p) { 30 | if (p < 0 || p >= parent!.length) { 31 | throw new Exception("p is out of bound."); 32 | } 33 | 34 | // 不断去查询自己的父亲节点, 直到到达根节点 35 | // 根节点的特点: parent[p] == p 36 | while (p != parent![p]) { 37 | p = parent![p]; 38 | } 39 | return p; 40 | } 41 | 42 | // 查看元素p和元素q是否所属一个集合 43 | // O(h)复杂度, h为树的高度 44 | @override 45 | bool isConnected(int p, int q) { 46 | return find(p) == find(q); 47 | } 48 | 49 | // 合并元素p和元素q所属的集合 50 | // O(h)复杂度, h为树的高度 51 | @override 52 | unionElements(int p, int q) { 53 | int pRoot = find(p); 54 | int qRoot = find(q); 55 | 56 | if (pRoot == qRoot) return; 57 | 58 | // 根据两个元素所在树的元素个数不同判断合并方向 59 | // 将元素个数少的集合合并到元素个数多的集合上 60 | if (sz![pRoot] < sz![qRoot]) { 61 | parent![pRoot] = qRoot; 62 | sz![qRoot] += sz![pRoot]; 63 | } else { 64 | // sz[qRoot] <= sz[pRoot] 65 | parent![qRoot] = pRoot; 66 | sz![pRoot] += sz![qRoot]; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /dart/18-Union-Find/UnionFind4.dart: -------------------------------------------------------------------------------- 1 | import 'UF.dart'; 2 | 3 | /** 4 | * 第四版并查集 5 | */ 6 | class UnionFind4 implements UF { 7 | List? rank; // rank[i]表示以i为根的集合所表示的树的层数 8 | List? parent; // parent[i]表示第i个元素所指向的父节点 9 | 10 | // 构造函数 11 | UnionFind4(int size) { 12 | rank = List.filled(size, num, growable: false); 13 | parent = List.filled(size, num, growable: false); 14 | 15 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 16 | for (var i = 0; i < size; i++) { 17 | parent![i] = i; 18 | rank![i] = 1; 19 | } 20 | } 21 | 22 | @override 23 | int? getSize() { 24 | return parent!.length; 25 | } 26 | 27 | // 查找过程, 查找元素p所对应的集合编号 28 | // O(h)复杂度, h为树的高度 29 | int find(int p) { 30 | if (p < 0 || p >= parent!.length) throw new Exception("p is out of bound."); 31 | 32 | // 不断去查询自己的父亲节点, 直到到达根节点 33 | // 根节点的特点: parent[p] == p 34 | while (p != parent![p]) { 35 | p = parent![p]; 36 | } 37 | return p; 38 | } 39 | 40 | // 查看元素p和元素q是否所属一个集合 41 | // O(h)复杂度, h为树的高度 42 | @override 43 | bool isConnected(int p, int q) { 44 | return find(p) == find(q); 45 | } 46 | 47 | // 合并元素p和元素q所属的集合 48 | // O(h)复杂度, h为树的高度 49 | @override 50 | unionElements(int p, int q) { 51 | int pRoot = find(p); 52 | int qRoot = find(q); 53 | 54 | if (pRoot == qRoot) return; 55 | 56 | // 根据两个元素所在树的rank不同判断合并方向 57 | // 将rank低的集合合并到rank高的集合上 58 | if (rank![pRoot] < rank![qRoot]) { 59 | parent![pRoot] = qRoot; 60 | } else if (rank![qRoot] < rank![pRoot]) { 61 | parent![qRoot] = pRoot; 62 | } else { 63 | // rank[pRoot] == rank[qRoot] 64 | parent![pRoot] = qRoot; 65 | rank![qRoot] += 1; // 此时, 我维护rank的值 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /dart/18-Union-Find/UnionFind5.dart: -------------------------------------------------------------------------------- 1 | import 'UF.dart'; 2 | 3 | /** 4 | * 第五版并查集 5 | */ 6 | class UnionFind5 extends UF { 7 | // rank[i]表示以i为根的集合所表示的树的层数 8 | // 在后续的代码中, 我们并不会维护rank的语意, 也就是rank的值在路径压缩的过程中, 有可能不在是树的层数值 9 | // 这也是我们的rank不叫height或者depth的原因, 他只是作为比较的一个标准 10 | List? rank; 11 | 12 | List? parent; // parent[i]表示第i个元素所指向的父节点 13 | 14 | // 构造函数 15 | UnionFind5(int size) { 16 | rank = List.filled(size, num, growable: false); 17 | parent = List.filled(size, num, growable: false); 18 | 19 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 20 | for (var i = 0; i < size; i++) { 21 | parent![i] = i; 22 | rank![i] = 1; 23 | } 24 | } 25 | 26 | @override 27 | int? getSize() { 28 | return parent!.length; 29 | } 30 | 31 | // 查找过程, 查找元素p所对应的集合编号 32 | // O(h)复杂度, h为树的高度 33 | int find(int p) { 34 | if (p < 0 || p >= parent!.length) { 35 | throw new Exception("p is out of bound."); 36 | } 37 | while (p != parent![p]) { 38 | parent![p] = parent![parent![p]]; 39 | p = parent![p]; 40 | } 41 | return p; 42 | } 43 | 44 | // 查看元素p和元素q是否所属一个集合 45 | // O(h)复杂度, h为树的高度 46 | @override 47 | bool isConnected(int p, int q) { 48 | return find(p) == find(q); 49 | } 50 | 51 | // 合并元素p和元素q所属的集合 52 | // O(h)复杂度, h为树的高度 53 | @override 54 | unionElements(int p, int q) { 55 | int pRoot = find(p); 56 | int qRoot = find(q); 57 | 58 | if (pRoot == qRoot) { 59 | return; 60 | } 61 | // 根据两个元素所在树的rank不同判断合并方向 62 | // 将rank低的集合合并到rank高的集合上 63 | if (rank![pRoot] < rank![qRoot]) { 64 | parent![pRoot] = qRoot; 65 | } else if (rank![qRoot] < rank![pRoot]) { 66 | parent![qRoot] = pRoot; 67 | } else { 68 | // rank[pRoot] == rank[qRoot] 69 | parent![pRoot] = qRoot; 70 | rank![qRoot] += 1; // 此时, 我维护rank的值 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /dart/18-Union-Find/UnionFind6.dart: -------------------------------------------------------------------------------- 1 | import 'UF.dart'; 2 | 3 | /** 4 | * 第六版 并查集 5 | */ 6 | class UnionFind6 implements UF { 7 | // rank[i]表示以i为根的集合所表示的树的层数 8 | // 在后续的代码中, 我们并不会维护rank的语意, 也就是rank的值在路径压缩的过程中, 有可能不在是树的层数值 9 | // 这也是我们的rank不叫height或者depth的原因, 他只是作为比较的一个标准 10 | List? rank; 11 | 12 | List? parent; // parent[i]表示第i个元素所指向的父节点 13 | 14 | // 构造函数 15 | UnionFind6(int size) { 16 | rank = List.filled(size, num, growable: false); 17 | parent = List.filled(size, num, growable: false); 18 | 19 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 20 | for (int i = 0; i < size; i++) { 21 | parent![i] = i; 22 | rank![i] = 1; 23 | } 24 | } 25 | 26 | @override 27 | int? getSize() { 28 | return parent!.length; 29 | } 30 | 31 | // 查找过程, 查找元素p所对应的集合编号 32 | // O(h)复杂度, h为树的高度 33 | int find(int p) { 34 | if (p < 0 || p >= parent!.length) throw new Exception("p is out of bound."); 35 | 36 | // path compression 2, 递归算法 37 | if (p != parent![p]) { 38 | parent![p] = find(parent![p]); 39 | } 40 | return parent![p]; 41 | } 42 | 43 | // 查看元素p和元素q是否所属一个集合 44 | // O(h)复杂度, h为树的高度 45 | @override 46 | bool isConnected(int p, int q) { 47 | return find(p) == find(q); 48 | } 49 | 50 | // 合并元素p和元素q所属的集合 51 | // O(h)复杂度, h为树的高度 52 | @override 53 | unionElements(int p, int q) { 54 | int pRoot = find(p); 55 | int qRoot = find(q); 56 | 57 | if (pRoot == qRoot) { 58 | return; 59 | } 60 | // 根据两个元素所在树的rank不同判断合并方向 61 | // 将rank低的集合合并到rank高的集合上 62 | if (rank![pRoot] < rank![qRoot]) { 63 | parent![pRoot] = qRoot; 64 | } else if (rank![qRoot] < rank![pRoot]) { 65 | parent![qRoot] = pRoot; 66 | } else { 67 | // rank[pRoot] == rank[qRoot] 68 | parent![pRoot] = qRoot; 69 | rank![qRoot] += 1; // 此时, 我维护rank的值 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dart/19-AVL-Tree/FileOperator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | /** 5 | * 文件操作类 6 | */ 7 | class FileOperator{ 8 | 9 | static Future getFileString(String filename) async{ 10 | Stream> content = File(filename).openRead(); 11 | List lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList(); 12 | var words = []; 13 | for(int i = 0;i element == ""); 17 | return words; 18 | } 19 | } -------------------------------------------------------------------------------- /dart/19-AVL-Tree/Main.dart: -------------------------------------------------------------------------------- 1 | import 'FileOperator.dart'; 2 | import 'BST.dart'; 3 | import 'AVLTree.dart'; 4 | 5 | 6 | void main() async{ 7 | 8 | print("Pride and Prejudice"); 9 | 10 | List words = await FileOperator.getFileString('text2.txt'); 11 | 12 | // words.sort(); 13 | 14 | // Test BST 15 | var now = new DateTime.now(); 16 | num startTime = now.millisecondsSinceEpoch; 17 | 18 | BST bst = BST(); 19 | for (String word in 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 in words) 27 | bst.contains(word); 28 | 29 | var endNow = new DateTime.now(); 30 | num endTime = endNow.millisecondsSinceEpoch; 31 | 32 | double time = (endTime - startTime) / 1000.0; 33 | print("BST: $time s"); 34 | 35 | // Test AVL 36 | var startNow1 = new DateTime.now(); 37 | var startTime1 = startNow1.millisecondsSinceEpoch; 38 | 39 | AVLTree avl = AVLTree(); 40 | for (String word in words) { 41 | if (avl.contains(word)) 42 | avl.set(word, avl.get(word) + 1); 43 | else 44 | avl.add(word, 1); 45 | } 46 | 47 | for(String word in words) 48 | avl.contains(word); 49 | var endNow1 = new DateTime.now(); 50 | var endTime1 = endNow1.millisecondsSinceEpoch; 51 | 52 | time = (endTime1 - startTime1) / 1000.0; 53 | print("AVL: $time s"); 54 | 55 | 56 | } -------------------------------------------------------------------------------- /dart/20-Red-Black-Tree/FileOperator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | /** 5 | * 文件操作类 6 | */ 7 | class FileOperator{ 8 | 9 | static Future getFileString(String filename) async{ 10 | Stream> content = File(filename).openRead(); 11 | List lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList(); 12 | var words = []; 13 | for(int i = 0;i element == ""); 17 | return words; 18 | } 19 | } -------------------------------------------------------------------------------- /dart/20-Red-Black-Tree/Main.dart: -------------------------------------------------------------------------------- 1 | import 'FileOperator.dart'; 2 | import 'BST.dart'; 3 | import 'AVLTree.dart'; 4 | import 'RBTree.dart'; 5 | 6 | 7 | void main() async{ 8 | 9 | print("Pride and Prejudice"); 10 | 11 | List words = await FileOperator.getFileString('text2.txt'); 12 | 13 | // words.sort(); 14 | 15 | // Test BST 16 | var now = new DateTime.now(); 17 | num startTime = now.millisecondsSinceEpoch; 18 | 19 | BST bst = BST(); 20 | for (String word in words) { 21 | if (bst.contains(word)) 22 | bst.set(word, bst.get(word) + 1); 23 | else 24 | bst.add(word, 1); 25 | } 26 | 27 | for(String word in words) 28 | bst.contains(word); 29 | 30 | var endNow = new DateTime.now(); 31 | num endTime = endNow.millisecondsSinceEpoch; 32 | 33 | double time = (endTime - startTime) / 1000.0; 34 | print("BST: $time s"); 35 | 36 | // Test AVL 37 | var startNow1 = new DateTime.now(); 38 | var startTime1 = startNow1.millisecondsSinceEpoch; 39 | 40 | AVLTree avl = AVLTree(); 41 | for (String word in words) { 42 | if (avl.contains(word)) 43 | avl.set(word, avl.get(word) + 1); 44 | else 45 | avl.add(word, 1); 46 | } 47 | 48 | for(String word in words) 49 | avl.contains(word); 50 | 51 | var endNow1 = new DateTime.now(); 52 | var endTime1 = endNow1.millisecondsSinceEpoch; 53 | 54 | double time3 = (endTime1 - startTime1) / 1000.0; 55 | print("AVL: $time3 s"); 56 | 57 | // Test BRTree 58 | var startNow2 = new DateTime.now(); 59 | var startTime2 = startNow2.millisecondsSinceEpoch; 60 | 61 | RBTree rb = RBTree(); 62 | for (String word in words) { 63 | if (rb.contains(word)) 64 | rb.set(word, rb.get(word) + 1); 65 | else 66 | rb.add(word, 1); 67 | } 68 | 69 | for(String word in words) 70 | avl.contains(word); 71 | var endNow2 = new DateTime.now(); 72 | var endTime2 = endNow2.millisecondsSinceEpoch; 73 | 74 | double time2 = (endTime2 - startTime2) / 1000.0; 75 | print("RBTree: $time2 s"); 76 | 77 | 78 | } -------------------------------------------------------------------------------- /dart/20-Red-Black-Tree/Main2.dart: -------------------------------------------------------------------------------- 1 | import 'BST.dart'; 2 | import 'AVLTree.dart'; 3 | import 'dart:math'; 4 | import 'RBTree.dart'; 5 | 6 | 7 | void main() async{ 8 | 9 | 10 | // int n = 20000000; 11 | int n = 1000000; 12 | 13 | Random random = new Random(n); 14 | 15 | List testData = List.empty(growable: true); 16 | 17 | for(int i = 0 ; i < n ; i ++) 18 | testData.add(random.nextInt(1<<32)); 19 | 20 | // Test BST 21 | var now = new DateTime.now(); 22 | num startTime = now.millisecondsSinceEpoch; 23 | 24 | BST bst = BST(); 25 | for (num x in testData) 26 | bst.add(x, 0); 27 | 28 | var endNow = new DateTime.now(); 29 | num endTime = endNow.millisecondsSinceEpoch; 30 | 31 | double time = (endTime - startTime) / 1000.0; 32 | print("BST: $time s"); 33 | 34 | // Test AVL 35 | var startNow1 = new DateTime.now(); 36 | var startTime1 = startNow1.millisecondsSinceEpoch; 37 | 38 | AVLTree avl = AVLTree(); 39 | for (num word in testData) { 40 | avl.add(word, 1); 41 | } 42 | var endNow1 = new DateTime.now(); 43 | var endTime1 = endNow1.millisecondsSinceEpoch; 44 | 45 | time = (endTime1 - startTime1) / 1000.0; 46 | print("AVL: $time s"); 47 | 48 | // Test BRTree 49 | var startNow2 = new DateTime.now(); 50 | var startTime2 = startNow2.millisecondsSinceEpoch; 51 | 52 | RBTree rb = RBTree(); 53 | for (num word in testData) { 54 | rb.add(word, 1); 55 | } 56 | 57 | var endNow2 = new DateTime.now(); 58 | var endTime2 = endNow2.millisecondsSinceEpoch; 59 | 60 | double time2 = (endTime2 - startTime2) / 1000.0; 61 | print("RBTree: $time2 s"); 62 | 63 | 64 | } -------------------------------------------------------------------------------- /dart/21-Hash-Table/FileOperator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | /** 5 | * 文件操作类 6 | */ 7 | class FileOperator{ 8 | 9 | static Future getFileString(String filename) async{ 10 | Stream> content = File(filename).openRead(); 11 | List lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList(); 12 | var words = []; 13 | for(int i = 0;i element == ""); 17 | return words; 18 | } 19 | } -------------------------------------------------------------------------------- /dart/21-Hash-Table/HashTable.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | /** 4 | * 哈希表 5 | */ 6 | class HashTable{ 7 | 8 | List? _hashtable; 9 | int? _size; 10 | int? _M; 11 | 12 | HashTable(int M){ 13 | this._M = M; 14 | _size = 0; 15 | _hashtable = List.filled(M, SplayTreeMap,growable: true); 16 | for(int i = 0 ; i < M ; i ++) 17 | _hashtable![i] =SplayTreeMap(); 18 | } 19 | 20 | factory HashTable.withFactory(){ 21 | return HashTable(97); 22 | } 23 | 24 | int _hash(K key){ 25 | return ((key.hashCode & 0x7fffffff) % _M!).toInt(); 26 | } 27 | 28 | int? getSize(){ 29 | return _size; 30 | } 31 | 32 | add(K key, V value){ 33 | SplayTreeMap map = _hashtable![_hash(key)]; 34 | if(map.containsKey(key)) 35 | map.update(key,(e)=>value); 36 | else{ 37 | map.putIfAbsent(key, ()=>value); 38 | _size = _size!+1; 39 | } 40 | } 41 | 42 | V? remove(K key){ 43 | V? ret = null; 44 | SplayTreeMap map = _hashtable![_hash(key)]; 45 | if(map.containsKey(key)){ 46 | ret = map.remove(key); 47 | _size = _size!+1; 48 | } 49 | return ret; 50 | } 51 | 52 | set(K key, V value){ 53 | SplayTreeMap map = _hashtable![_hash(key)]; 54 | if(!map.containsKey(key)) { 55 | throw new Exception("$key doesn't exist!"); 56 | } 57 | map.update(key, (e)=>value); 58 | } 59 | 60 | bool contains(K key){ 61 | return _hashtable![_hash(key)].containsKey(key); 62 | } 63 | 64 | V? get(K key){ 65 | return _hashtable![_hash(key)][key]; 66 | } 67 | } -------------------------------------------------------------------------------- /dart/21-Hash-Table/HashTableSec.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | /** 4 | * 哈希表重构 5 | */ 6 | class HashTableSec { 7 | List? _hashtable; 8 | 9 | int? _size; 10 | 11 | int? _M; 12 | 13 | static final int _upperTol = 10; 14 | static final int _lowerTol = 2; 15 | static final int _initCapacity = 7; 16 | 17 | HashTableSec(int M) { 18 | this._M = M; 19 | _size = 0; 20 | _hashtable = List.filled(M, SplayTreeMap, growable: true); 21 | for (int i = 0; i < M; i++) { 22 | _hashtable![i] = SplayTreeMap(); 23 | } 24 | } 25 | 26 | factory HashTableSec.withFactory() { 27 | return HashTableSec(_initCapacity); 28 | } 29 | 30 | int _hash(K key) { 31 | return ((key.hashCode & 0x7fffffff) % _M!).toInt(); 32 | } 33 | 34 | int? getSize() { 35 | return _size; 36 | } 37 | 38 | add(K key, V value) { 39 | SplayTreeMap map = _hashtable![_hash(key)]; 40 | if (map.containsKey(key)) 41 | map.update(key, (e) => value); 42 | else { 43 | map.putIfAbsent(key, () => value); 44 | _size = _size! + 1; 45 | 46 | if (_size! >= _upperTol * _M!) _resize(2 * _M!); 47 | } 48 | } 49 | 50 | V? remove(K key) { 51 | V? ret = null; 52 | SplayTreeMap map = _hashtable![_hash(key)]; 53 | if (map.containsKey(key)) { 54 | ret = map.remove(key); 55 | _size = _size! + 1; 56 | 57 | if(_size! < _lowerTol * _M! && _M! / 2 >= _initCapacity) { 58 | _resize((_M!/ 2).toInt()); 59 | } 60 | } 61 | return ret; 62 | } 63 | 64 | set(K key, V value) { 65 | SplayTreeMap map = _hashtable![_hash(key)]; 66 | if (!map.containsKey(key)) { 67 | throw new Exception("$key doesn't exist!"); 68 | } 69 | map.update(key, (e) => value); 70 | } 71 | 72 | bool contains(K key) { 73 | return _hashtable![_hash(key)].containsKey(key); 74 | } 75 | 76 | V? get(K key) { 77 | return _hashtable![_hash(key)][key]; 78 | } 79 | 80 | /** 81 | * 设置尺寸 82 | */ 83 | _resize(int newM) { 84 | // SplayTreeMap[] newHashTable = new SplayTreeMap[newM]; 85 | List _newHashtable = List.filled(newM, SplayTreeMap, growable: true); 86 | for (int i = 0; i < newM; i++) { 87 | _newHashtable[i] = SplayTreeMap(); 88 | } 89 | int oldM = _M!; 90 | this._M = newM; 91 | for (int i = 0; i < oldM; i++) { 92 | SplayTreeMap map = _hashtable![i]; 93 | for (K key in map.keys) { 94 | _newHashtable[_hash(key)].put(key, map[key]); 95 | }; 96 | } 97 | 98 | this._hashtable = _newHashtable; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /dart/21-Hash-Table/Main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'FileOperator.dart'; 3 | import 'HashTableSec.dart'; 4 | 5 | void main() async{ 6 | int a = 42; 7 | print(a.hashCode); 8 | int b = -42; 9 | print(b.hashCode); 10 | double c = 3.1415926; 11 | print(c.hashCode); 12 | String d = "abcd"; 13 | print(d.hashCode); 14 | 15 | HashSet set = HashSet(); 16 | 17 | HashMap map = HashMap(); 18 | 19 | 20 | List words = await FileOperator.getFileString('text2.txt'); 21 | 22 | // words.sort(); 23 | 24 | // Test HashTable 25 | var now = new DateTime.now(); 26 | num startTime = now.millisecondsSinceEpoch; 27 | 28 | // HashTable hashtable = HashTable(131071); 29 | HashTableSec hashtable = HashTableSec(131071); 30 | for (String word in words) { 31 | if (hashtable.contains(word)) 32 | hashtable.set(word, hashtable.get(word)! + 1); 33 | else 34 | hashtable.add(word, 1); 35 | } 36 | 37 | for(String word in words) { 38 | hashtable.contains(word); 39 | } 40 | var endNow = new DateTime.now(); 41 | num endTime = endNow.millisecondsSinceEpoch; 42 | 43 | double time = (endTime - startTime) / 1000.0; 44 | print("HashTable: $time s"); 45 | 46 | } -------------------------------------------------------------------------------- /dart/21-Hash-Table/Solution.dart: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * dart中无类型提升 4 | * dart中不能让字符串与数字相加,比如将数字转为字符串才能相加,其实就是字符串链接 5 | */ 6 | class Solution { 7 | firstUniqChar(String s) { 8 | 9 | List freq = List.empty(growable: true); 10 | for(int i = 0 ; i < s.length ; i ++) { 11 | freq[s[i].codeUnits[0] - 'a'.codeUnits[0]] ++; 12 | } 13 | for(int i = 0 ; i < s.length ; i ++) { 14 | if (s[i].codeUnits[0] - 'a'.codeUnits[0] == 1) { 15 | return i; 16 | } 17 | } 18 | 19 | return -1; 20 | } 21 | } -------------------------------------------------------------------------------- /dart/22-CountingSort-And-RadixSort/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i= 0; r--) { 14 | // O(n) 15 | List cnt = List.filled(R, 0, growable: true); 16 | for (String s in arr) { 17 | cnt[s[r].codeUnits[0]]++; 18 | } 19 | // O(R) 20 | for (int i = 0; i < R; i++) { 21 | index[i + 1] = index[i] + cnt[i]; 22 | } 23 | // O(n) 24 | for (String s in arr) { 25 | temp[index[s[r].codeUnits[0]]] = s; 26 | index[s[r].codeUnits[0]]++; 27 | } 28 | // O(n) 29 | for (int i = 0; i < arr.length; i++) arr[i] = temp[i]; 30 | } 31 | } 32 | 33 | 34 | } 35 | 36 | void main() { 37 | List arr = ["BCA", "CAB", "ACB", "BAC", "ABC", "CBA"]; 38 | LSDSort.sort(arr, 3); 39 | for (String s in arr) { 40 | print(s); 41 | } 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /dart/22-CountingSort-And-RadixSort/Main.dart: -------------------------------------------------------------------------------- 1 | import 'Student.dart'; 2 | import 'dart:math'; 3 | 4 | void main() { 5 | print("abcdefghijklmnopqrstuvwxyz".codeUnits); 6 | print("abcdefghijklmnopqrstuvwxyz".runes); 7 | print(String.fromCharCode("abcdefghijklmnopqrstuvwxyz".codeUnits[0])); 8 | print(String.fromCharCode("abcdefghijklmnopqrstuvwxyz".codeUnits[0])); 9 | Iterable? string = [ 10 | 97, 11 | 98, 12 | 99, 13 | 100, 14 | 101, 15 | 102, 16 | 103, 17 | 104, 18 | 105, 19 | 106, 20 | 107, 21 | 108, 22 | 109, 23 | 110, 24 | 111, 25 | 112, 26 | 113, 27 | 114, 28 | 115, 29 | 116, 30 | 117, 31 | 118, 32 | 119, 33 | 120, 34 | 121, 35 | 122 36 | ]; 37 | print(String.fromCharCodes(string, 0, 26)); 38 | 39 | int n = 26 * 26 * 26 * 26; 40 | 41 | List students = List.filled(n, Student, growable: true); 42 | int k = 0; 43 | Random rnd = new Random(); 44 | for (var c1 = 'a'.codeUnits[0]; c1 <= 'z'.codeUnits[0]; c1++) 45 | for (var c2 = 'a'.codeUnits[0]; c2 <= 'z'.codeUnits[0]; c2++) 46 | for (var c3 = 'a'.codeUnits[0]; c3 <= 'z'.codeUnits[0]; c3++) 47 | for (var c4 = 'a'.codeUnits[0]; c4 <= 'z'.codeUnits[0]; c4++) { 48 | students[k] = new Student( 49 | "${String.fromCharCode(c1)} + ${String.fromCharCode(c2)} + ${String.fromCharCode(c3)} + ${String.fromCharCode(c4)}", 50 | rnd.nextInt(101)); 51 | k++; 52 | } 53 | 54 | // 计数排序过程 55 | int R = 101; 56 | 57 | // O(n) 58 | List cnt = List.filled(R, 0, growable: true); 59 | for (Student student in students) { 60 | cnt[student.getScore()!] = cnt[student.getScore()!] +1; 61 | }; 62 | 63 | // O(R) 64 | List index = List.filled(R + 1, 0, growable: true); 65 | for (int i = 0; i < R; i++) index[i + 1] = index[i] + cnt[i]; 66 | 67 | // O(n) 68 | List temp = List.filled(n, Student, growable: true); 69 | for (Student student in students) { 70 | temp[index[student.getScore()!]] = student; 71 | index[student.getScore()!]++; 72 | } 73 | 74 | // O(n) 75 | for (int i = 0; i < n; i++) students[i] = temp[i]; 76 | 77 | // O(n + R) 78 | 79 | // 验证计数排序算法 80 | for (int i = 1; i < n; i++) { 81 | if (students[i - 1].getScore() > students[i].getScore()) 82 | throw new Exception("Sort failed"); 83 | 84 | if (students[i - 1].getScore() == students[i].getScore()) { 85 | if (students[i - 1].getName().compareTo(students[i].getName()) >= 0) 86 | throw new Exception("Non-Stable counting sort!"); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /dart/22-CountingSort-And-RadixSort/ShellSort.dart: -------------------------------------------------------------------------------- 1 | import 'SortingHelper.dart'; 2 | import 'ArrayGenerator.dart'; 3 | 4 | /** 5 | * 希尔排序 6 | */ 7 | class ShellSort { 8 | //初始版本 9 | static sort(List? data) { 10 | int h = (data!.length / 2).toInt(); 11 | while (h >= 1) { 12 | for (int start = 0; start < h; start++) { 13 | // 对 data[start, start + h, start + 2h, start + 3h ...], 进行插入排序 14 | for (int i = start + h; i < data.length; i += h) { 15 | var t = data[i]; 16 | int j; 17 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) 18 | data[j] = data[j - h]; 19 | data[j] = t; 20 | } 21 | } 22 | h = (h / 2).toInt(); 23 | } 24 | } 25 | 26 | //希尔排序优化 27 | static sort2(List? data) { 28 | int h = (data!.length / 2).toInt(); 29 | while (h >= 1) { 30 | for (int i = h; i < data.length; i++) { 31 | var t = data[i]; 32 | int j; 33 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) { 34 | data[j] = data[j - h]; 35 | } 36 | data[j] = t; 37 | } 38 | h = (h / 2).toInt(); 39 | } 40 | } 41 | 42 | //希尔排序设定步长序列 43 | static sort3(List? data) { 44 | int h = 1; 45 | while (h < data!.length) { 46 | h = 3 * h + 1; 47 | } 48 | // 1, 4, 13, 40 ... 49 | while (h >= 1) { 50 | for (int i = h; i < data.length; i++) { 51 | var t = data[i]; 52 | int j; 53 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) { 54 | data[j] = data[j - h]; 55 | } 56 | data[j] = t; 57 | } 58 | h = (h / 3).toInt(); 59 | } 60 | } 61 | } 62 | 63 | void main() { 64 | int n = 100000; 65 | List arr = ArrayGenerator.generateRandomArray(n, n); 66 | 67 | SortingHelper.sortTest("ShellSort", arr); 68 | } 69 | -------------------------------------------------------------------------------- /dart/22-CountingSort-And-RadixSort/Solution.dart: -------------------------------------------------------------------------------- 1 | class Solution { 2 | sortColors(List nums) { 3 | List? cnt = List.filled(3, 0, growable: true); 4 | for (int num in nums) { 5 | cnt[num]++;} 6 | 7 | for (int i = 0; i < cnt[0]; i++) { 8 | nums[i] = 0; 9 | } 10 | for (int i = cnt[0]; i < cnt[0] + cnt[1]; i++) { 11 | nums[i] = 1; 12 | } 13 | for (int i = cnt[0] + cnt[1]; i < cnt[0] + cnt[1] + cnt[2]; i++) { 14 | nums[i] = 2; 15 | } 16 | } 17 | 18 | sortColors2(List nums) { 19 | // 处理元素取值范围是 [0, R) 的计数排序 20 | int R = 3; 21 | 22 | List? cnt = List.filled(3, 0, growable: true); 23 | for (int num in nums) { 24 | cnt[num]++; 25 | } 26 | 27 | // [index[i], index[i + 1]) 的值为 i 28 | List? index = List.filled(R + 1, , int, growable: true); 29 | for (int i = 0; i < R; i++) { 30 | index[i + 1] = index[i] + cnt[i]; 31 | } 32 | 33 | for (int i = 0; i + 1 < index.length; i++) { 34 | // [index[i], index[i + 1]) 的值为 i 35 | for (int j = index[i]; j < index[i + 1]; j++){ 36 | nums[j] = i; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dart/22-CountingSort-And-RadixSort/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | import 'ShellSort.dart'; 2 | 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List? arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | ShellSort.sort(arr); 38 | } 39 | var endNow = new DateTime.now(); 40 | num endTime = endNow.millisecondsSinceEpoch; 41 | print("开始时间:$startTime : 结束时间:$endTime"); 42 | double time = (endTime - startTime) / 1000.0; 43 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 44 | print("$sortname , n = ${arr!.length}: $time s"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/22-CountingSort-And-RadixSort/Student.dart: -------------------------------------------------------------------------------- 1 | class Student { 2 | 3 | String? name; 4 | int? score; 5 | 6 | Student(this.name,this.score); 7 | 8 | @override 9 | num? compareTo(other) { 10 | return this.score! - other.score; 11 | } 12 | 13 | String? getName(){ 14 | return name; 15 | } 16 | 17 | int? getScore(){ 18 | return score; 19 | } 20 | 21 | @override 22 | toString(){ 23 | return "Student(name: $name, score: $score)"; 24 | } 25 | } -------------------------------------------------------------------------------- /dart/23-MSDSort-And-BucketSort/ArrayGenerator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class ArrayGenerator{ 4 | 5 | static List generateOrderedArray(int n){ 6 | List arr = List.filled(n, true); 7 | for(int i = 0;i arr, int B) { 8 | if (B <= 1) throw new Exception("B must be > 1"); 9 | 10 | List temp = List.filled(arr.length, 0, growable: true); 11 | _sortDetail(arr, 0, arr.length - 1, B, temp); 12 | } 13 | 14 | static _sortDetail(List arr, int left, int right, int B, List? temp) { 15 | if (left >= right) return; 16 | 17 | int maxv = 1 >> 32, minv = 1 << 32; 18 | for (int i = left; i <= right; i++) { 19 | maxv = [maxv, arr[i]].reduce(max); 20 | minv = [minv, arr[i]].reduce(min); 21 | } 22 | 23 | if (maxv == minv) {return;} 24 | 25 | int d = 26 | ((maxv - minv + 1) / B).toInt() + ((maxv - minv + 1) % B > 0 ? 1 : 0); 27 | 28 | List cnt = List.filled(B, 0, growable: true); 29 | List index = List.filled(B + 1, 0, growable: true); 30 | 31 | // O(n) 32 | for (int i = left; i <= right; i++) cnt[((arr[i] - minv) / d).toInt()]++; 33 | 34 | // O(R) 35 | for (int i = 0; i < B; i++) { 36 | index[i + 1] = index[i] + cnt[i]; 37 | } 38 | // O(n) 39 | for (int i = left; i <= right; i++) { 40 | int p = ((arr[i] - minv) / d).toInt(); 41 | temp![(left + index[p]).toInt()] = arr[i]; 42 | index[p]++; 43 | } 44 | 45 | // O(n) 46 | for (int i = left; i <= right; i++) { 47 | arr[i] = temp![i]; 48 | } 49 | 50 | // 递归下去: 51 | _sortDetail(arr, left, (left + index[0] - 1).toInt(), B, temp); 52 | for (int i = 0; i < B - 1; i++) 53 | _sortDetail(arr, (left + index[i]).toInt(), 54 | (left + index[i + 1] - 1).toInt(), B, temp); 55 | } 56 | 57 | static sort2(List arr, int c) { 58 | if (c <= 0) throw new Exception("c must be > 0"); 59 | 60 | int maxv = 1 >> 32, minv = 1 << 32; 61 | for (int e in arr) { 62 | maxv = [maxv, e].reduce(max); 63 | minv = [minv, e].reduce(min); 64 | } 65 | 66 | int range = maxv - minv + 1; // arr 中的数据范围 67 | int B = (range / c).toInt() + (range % c > 0 ? 1 : 0); // 根据数据范围决定桶的个数 68 | 69 | List buckets = List.filled(B, List, growable: true); 70 | // for(int i = 0; i < B; i ++) 71 | // buckets[i] = new LinkedList<>(); 72 | for (int e in arr) { 73 | buckets[((e - minv) / range).toInt()].add(e); 74 | } 75 | for (int i = 0; i < B; i++) { 76 | buckets[i].sort(); 77 | } 78 | int index = 0; 79 | for (int i = 0; i < B; i++) for (int e in buckets[i]) { 80 | arr[index++] = e; 81 | } 82 | } 83 | } 84 | 85 | void main() { 86 | int n = 1000000; 87 | List? arr = ArrayGenerator.generateRandomArray(n, n); 88 | List? arr2 = List.from(arr); 89 | 90 | //SortingHelper.sortTest("BucketSort", arr); 91 | //SortingHelper.sortTest("BucketSort2", arr2); 92 | } 93 | -------------------------------------------------------------------------------- /dart/23-MSDSort-And-BucketSort/MSDSort.dart: -------------------------------------------------------------------------------- 1 | class MSDSort { 2 | MSDSort() {} 3 | 4 | static sort(List? arr) { 5 | int N = arr!.length; 6 | List? temp = List.filled(N, String, growable: true); 7 | _sortDetail(arr, 0, N - 1, 0, temp); 8 | } 9 | 10 | static _sortDetail(List? arr, int left, int right, int r, List? temp) { 11 | if (left >= right) return; 12 | 13 | int R = 256; 14 | List? cnt = List.filled(R + 1, 0, growable: true); 15 | List? index = List.filled(R + 2, 0, growable: true); 16 | 17 | // O(n) 18 | for (int i = left; i <= right; i++) { 19 | cnt[r >= arr![i].length ? 0 : (arr[i][r].codeUnits[0] + 1)]++; 20 | } 21 | // O(R) 22 | for (int i = 0; i < R + 1; i++) { 23 | index[i + 1] = index[i] + cnt[i]; 24 | } 25 | // O(n) 26 | for (int i = left; i <= right; i++) { 27 | temp![index[r >= arr![i].length ? 0 : (arr[i][r].codeUnits[0] + 1)] + 28 | left] = arr[i]; 29 | index[r >= arr[i].length ? 0 : (arr[i][r].codeUnits[0] + 1)]++; 30 | } 31 | 32 | // O(n) 33 | for (int i = left; i <= right; i++) { 34 | arr![i] = temp![i]; 35 | } 36 | 37 | for (int i = 0; i < R; i++) { 38 | _sortDetail(arr, (left + index[i]).toInt(), 39 | (left + index[i + 1] - 1).toInt(), r + 1, temp); 40 | } 41 | } 42 | } 43 | 44 | void main() { 45 | List? arr = ["BCA", "CBAA", "AC", "BADFE", "ABC", "CBA"]; 46 | MSDSort.sort(arr); 47 | for (String s in arr) { 48 | print(s); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dart/23-MSDSort-And-BucketSort/ShellSort.dart: -------------------------------------------------------------------------------- 1 | import 'SortingHelper.dart'; 2 | import 'ArrayGenerator.dart'; 3 | 4 | /** 5 | * 希尔排序 6 | */ 7 | class ShellSort { 8 | //初始版本 9 | static sort(List? data) { 10 | int h = (data!.length / 2).toInt(); 11 | while (h >= 1) { 12 | for (int start = 0; start < h; start++) { 13 | // 对 data[start, start + h, start + 2h, start + 3h ...], 进行插入排序 14 | for (int i = start + h; i < data.length; i += h) { 15 | var t = data[i]; 16 | int j; 17 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) 18 | data[j] = data[j - h]; 19 | data[j] = t; 20 | } 21 | } 22 | h = (h / 2).toInt(); 23 | } 24 | } 25 | 26 | //希尔排序优化 27 | static sort2(List? data) { 28 | int h = (data!.length / 2).toInt(); 29 | while (h >= 1) { 30 | for (int i = h; i < data.length; i++) { 31 | var t = data[i]; 32 | int j; 33 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) { 34 | data[j] = data[j - h]; 35 | } 36 | data[j] = t; 37 | } 38 | h = (h / 2).toInt(); 39 | } 40 | } 41 | 42 | //希尔排序设定步长序列 43 | static sort3(List? data) { 44 | int h = 1; 45 | while (h < data!.length) { 46 | h = 3 * h + 1; 47 | } 48 | // 1, 4, 13, 40 ... 49 | while (h >= 1) { 50 | for (int i = h; i < data.length; i++) { 51 | var t = data[i]; 52 | int j; 53 | for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) { 54 | data[j] = data[j - h]; 55 | } 56 | data[j] = t; 57 | } 58 | h = (h / 3).toInt(); 59 | } 60 | } 61 | } 62 | 63 | void main() { 64 | int n = 100000; 65 | List arr = ArrayGenerator.generateRandomArray(n, n); 66 | 67 | SortingHelper.sortTest("ShellSort", arr); 68 | } 69 | -------------------------------------------------------------------------------- /dart/23-MSDSort-And-BucketSort/SortingHelper.dart: -------------------------------------------------------------------------------- 1 | import 'ShellSort.dart'; 2 | import 'BucketSort.dart'; 3 | class SortingHelper { 4 | SortingHelper() {} 5 | 6 | static bool isSorted(List? arr) { 7 | for (int i = 1; i < arr!.length; i++) 8 | if (arr[i - 1].compareTo(arr[i]) > 0) return false; 9 | return true; 10 | } 11 | 12 | static sortTest(String sortname, List arr) { 13 | var now = new DateTime.now(); 14 | num startTime = now.millisecondsSinceEpoch; 15 | 16 | if (sortname == "SelectionSort") { 17 | // SelectionSort.sort(arr); 18 | } else if (sortname == "InsertionSort") { 19 | // InsertionSort.sort(arr); 20 | } else if (sortname == "MergeSort") { 21 | // MergeSort.sort(arr); 22 | } else if (sortname == "MergeSortBU") { 23 | // MergeSort.sortBU(arr); 24 | } else if (sortname == "QuickSort") { 25 | // QuickSort.sort(arr); 26 | } else if (sortname == "QuickSort2Ways") { 27 | // QuickSort.sort2ways(arr); 28 | } else if (sortname == "QuickSort3Ways") { 29 | // QuickSort.sort3ways(arr); 30 | } else if (sortname == "QuickSort3Ways") { 31 | // QuickSort.sort3ways(arr); 32 | } else if (sortname == "HeapSort") { 33 | // HeapSort.sort(arr); 34 | } else if (sortname == "BubbleSort") { 35 | // BubbleSort.sort(arr); 36 | } else if (sortname == "ShellSort") { 37 | ShellSort.sort(arr); 38 | }else if(sortname == "BucketSort"){ 39 | // BucketSort.sort(arr, 200); 40 | } 41 | var endNow = new DateTime.now(); 42 | num endTime = endNow.millisecondsSinceEpoch; 43 | print("开始时间:$startTime : 结束时间:$endTime"); 44 | double time = (endTime - startTime) / 1000.0; 45 | if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed"); 46 | print("$sortname , n = ${arr.length}: $time s"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dart/24-SubString-Match/FileOperator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | /** 5 | * 文件操作类 6 | */ 7 | class FileOperator{ 8 | 9 | static Future getFileString(String filename) async{ 10 | Stream> content = File(filename).openRead(); 11 | List lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList(); 12 | var words = []; 13 | for(int i = 0;i element == ""); 17 | return words; 18 | } 19 | } -------------------------------------------------------------------------------- /dart/24-SubString-Match/LC1392-hash.dart: -------------------------------------------------------------------------------- 1 | class Solution2 { 2 | double MOD = 1e9 + 7; 3 | 4 | String longestPrefix(String s) { 5 | List pow26 = List.filled(s.length, 0, growable: true); 6 | pow26[0] = 1; 7 | for (int i = 1; i < pow26.length; i++) 8 | pow26[i] = (pow26[i - 1] * 26 % MOD).toInt(); 9 | 10 | // prehash[i]: hash(s[0...i]) 11 | List prehash = List.filled(s.length, 0, growable: true); 12 | prehash[0] = s[0].codeUnits[0] - 'a'.codeUnits[0]; 13 | for (int i = 1; i < s.length; i++) 14 | prehash[i] = 15 | ((prehash[i - 1] * 26 + s[i].codeUnits[0] - 'a'.codeUnits[0]) % MOD) 16 | .toInt(); 17 | 18 | // posthash[i]: hash(s[i...s.length - 1]) 19 | List posthash = List.filled(s.length, 0, growable: true); 20 | posthash[s.length - 1] = s[s.length - 1].codeUnits[0] - 'a'.codeUnits[0]; 21 | for (int i = s.length - 2; i >= 0; i--) 22 | posthash[i] = 23 | ((pow26[s.length - i - 1] * (s[i].codeUnits[0] - 'a'.codeUnits[0]) + 24 | posthash[i + 1]) % 25 | MOD) 26 | .toInt(); 27 | 28 | // s[0...len - 1], s[s.length - len...s.length - 1] 29 | for (int len = s.length - 1; len >= 1; len--) { 30 | if (prehash[len - 1] == posthash[s.length - len] && 31 | _equal(s, 0, len - 1, s.length - len, s.length - 1)) 32 | return s.substring(0, len); 33 | } 34 | return ""; 35 | } 36 | 37 | bool _equal(String s, int l1, int r1, int l2, int r2) { 38 | for (int i = l1, j = l2; i <= r1 && j <= r2; i++, j++) 39 | if (s[i] != s[j]) return false; 40 | return true; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dart/24-SubString-Match/LC1392.dart: -------------------------------------------------------------------------------- 1 | class Solution { 2 | 3 | String longestPrefix(String s) { 4 | 5 | // s[0...len - 1], s[s.length - len...s.length - 1] 6 | for(int len = s.length - 1; len >= 1; len --) 7 | if(_equal(s, 0, len - 1, s.length - len, s.length - 1)) 8 | return s.substring(0, len); 9 | return ""; 10 | } 11 | 12 | bool _equal(String s, int l1, int r1, int l2, int r2){ 13 | 14 | for(int i = l1, j = l2; i <= r1 && j <= r2; i ++, j ++) 15 | if(s[i] != s[j]) return false; 16 | return true; 17 | } 18 | 19 | 20 | } 21 | 22 | void main() { 23 | 24 | print((new Solution()).longestPrefix("level")); 25 | } 26 | -------------------------------------------------------------------------------- /dart/24-SubString-Match/LC187-RollingHash.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | class Solution2 { 3 | List findRepeatedDnaSequences(String s) { 4 | 5 | if(s.length < 10) { 6 | return List.empty(growable: true); 7 | }; 8 | 9 | List map = List.filled(256,0, growable: true); 10 | map['A'.codeUnits[0]] = 1; 11 | map['C'.codeUnits[0]] = 2; 12 | map['G'.codeUnits[0]] = 3; 13 | map['T'.codeUnits[0]] = 4; 14 | 15 | HashSet seen = new HashSet(); 16 | HashSet res = new HashSet(); 17 | 18 | int hash = 0; 19 | double ten9 = 1e9; 20 | 21 | for(int i = 0; i < 9; i ++) 22 | hash = hash * 10 + map[s[i].codeUnits[0]]; 23 | 24 | for(int i = 9; i < s.length; i ++){ 25 | 26 | hash = hash * 10 + map[s[i].codeUnits[0]]; 27 | 28 | if(seen.contains(hash)) res.add(s.substring(i - 9, i + 1)); 29 | else seen.add(hash); 30 | 31 | hash -= (map[s[i - 9].codeUnits[0]] * ten9).toInt(); 32 | } 33 | return res.toList(); 34 | } 35 | } -------------------------------------------------------------------------------- /dart/24-SubString-Match/LC187.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | class Solution { 3 | List findRepeatedDnaSequences(String s) { 4 | 5 | HashSet seen = HashSet(); 6 | HashSet res = HashSet(); 7 | for(int i = 0; i + 10 <= s.length; i ++){ 8 | String key = s.substring(i, i + 10); 9 | if(seen.contains(key)) 10 | res.add(key); 11 | else 12 | seen.add(key); 13 | } 14 | return res.toList(); 15 | } 16 | } -------------------------------------------------------------------------------- /dart/24-SubString-Match/Solution.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 1147号问题使用遍历查询 3 | */ 4 | class Solution { 5 | int longestDecomposition(String text) { 6 | return _solve(text, 0, text.length - 1); 7 | } 8 | 9 | int _solve(String s, int left, int right) { 10 | if (left > right) return 0; 11 | 12 | for (int i = left, j = right; i < j; i++, j--) { 13 | if (_equal(s, left, i, j, right)) return 2 + _solve(s, i + 1, j - 1); 14 | } 15 | return 1; 16 | } 17 | 18 | bool _equal(String s, int l1, int r1, int l2, int r2) { 19 | for (int i = l1, j = l2; i <= r1 && j <= r2; i++, j++) 20 | if (s[i] != s[j]) return false; 21 | return true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dart/24-SubString-Match/Solution2.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 1147号问题使用hash值解决 3 | */ 4 | class Solution2 { 5 | double MOD = 1e9 + 7; 6 | 7 | List? pow26; 8 | 9 | int longestDecomposition(String text) { 10 | pow26 = List.filled(text.length, 0, growable: true); 11 | pow26![0] = 1; 12 | for (int i = 1; i < pow26!.length; i++) 13 | pow26![i] = pow26![i - 1] * 26 % MOD; 14 | 15 | return _solve(text, 0, text.length - 1); 16 | } 17 | 18 | int _solve(String s, int left, int right) { 19 | if (left > right) return 0; 20 | 21 | int prehash = 0, posthash = 0; 22 | for (int i = left, j = right; i < j; i++, j--) { 23 | prehash = ((prehash * 26 + (s[i].codeUnits[0] - 'a'.codeUnits[0])) % MOD) 24 | .toInt(); 25 | posthash = (((s[j].codeUnits[0] - 'a'.codeUnits[0]) * pow26![right - j] + 26 | posthash) % 27 | MOD) 28 | .toInt(); 29 | 30 | if (prehash == posthash && _equal(s, left, i, j, right)) 31 | return 2 + _solve(s, i + 1, j - 1); 32 | } 33 | return 1; 34 | } 35 | 36 | bool _equal(String s, int l1, int r1, int l2, int r2) { 37 | for (int i = l1, j = l2; i <= r1 && j <= r2; i++, j++) 38 | if (s[i] != s[j]) return false; 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dart/24-SubString-Match/SubstringMatch.dart: -------------------------------------------------------------------------------- 1 | import 'SubstringMatchHelper.dart'; 2 | import 'FileOperator.dart'; 3 | 4 | /** 5 | * 字符串匹配 6 | */ 7 | class SubstringMatch { 8 | //粗暴强制 9 | static int bruteforce(String s, String t) { 10 | if (s.length < t.length) return -1; 11 | // s[i, i + t.length - 1] 12 | for (int i = 0; i + t.length - 1 < s.length; i++) { 13 | int j = 0; 14 | for (; j < t.length; j++) 15 | if (s[i + j] != t[j]) break; 16 | if (j == t.length) return i; 17 | } 18 | return -1; 19 | } 20 | 21 | static int rabinKarp(String s, String t) { 22 | if (s.length < t.length) return -1; 23 | if (t.length == 0) return 0; 24 | 25 | int thash = 0, 26 | B = 256; 27 | double MOD = 1e9 + 7; 28 | for(int i = 0; i < t.length; i ++){ 29 | thash = ((thash * B + t[i].codeUnits[0]) % MOD).toInt(); 30 | }; 31 | int hash = 0, P = 1; 32 | for(int i = 0; i < t.length - 1; i ++) 33 | P = (P * B % MOD).toInt(); 34 | 35 | for(int i = 0; i < t.length - 1; i ++) 36 | hash = ((hash * B + s[i].codeUnits[0]) % MOD).toInt(); 37 | 38 | for(int i = t.length- 1; i < s.length; i ++){ 39 | hash = ((hash * B + s[i].codeUnits[0]) % MOD).toInt(); 40 | if(hash == thash && _equal(s, i - t.length + 1, t)) 41 | return i - t.length + 1; 42 | hash = ((hash - s[i - t.length + 1].codeUnits[0] * P % MOD + MOD) % MOD).toInt(); 43 | } 44 | return 45 | - 46 | 1; 47 | } 48 | 49 | static bool _equal(String s, int l, String t) { 50 | for (int i = 0; i < t.length; i ++) 51 | if (s[l].codeUnits[0] + i != t[i].codeUnits[0]) return false; 52 | return true; 53 | } 54 | } 55 | 56 | void main() async { 57 | String s1 = "hello, this is liuyubobobo."; 58 | String t1 = "bo"; 59 | SubstringMatchHelper.matchTest("bruteforce", s1, t1); 60 | 61 | List s2 = await FileOperator.getFileString("text2.txt"); 62 | String t2 = "china"; 63 | StringBuffer res = new StringBuffer(); 64 | for (int i = 0; i < s2.length; i++) { 65 | res.write(s2[i]); 66 | } 67 | 68 | SubstringMatchHelper.matchTest("bruteforce", res.toString(), t2); 69 | 70 | SubstringMatchHelper.matchTest("bruteforce", res.toString(), "zyx"); 71 | 72 | /// Worst case 73 | int n = 1000000, 74 | m = 1000; 75 | 76 | StringBuffer s3 = new StringBuffer(); 77 | for (int i = 0; i < n; i++) 78 | s3.write('a'); 79 | 80 | StringBuffer t3 = new StringBuffer(); 81 | for (int i = 0; i < m - 1; i++) 82 | t3.write('a'); 83 | t3.write('b'); 84 | 85 | SubstringMatchHelper.matchTest("bruteforce", s3.toString(), t3.toString()); 86 | } 87 | -------------------------------------------------------------------------------- /dart/24-SubString-Match/SubstringMatchHelper.dart: -------------------------------------------------------------------------------- 1 | import 'SubstringMatch.dart'; 2 | class SubstringMatchHelper { 3 | 4 | SubstringMatchHelper(){} 5 | 6 | static void matchTest(String name, String s, String t){ 7 | 8 | int pos = -1; 9 | 10 | int startTime = new DateTime.now().millisecondsSinceEpoch; 11 | if(name == "bruteforce"){ 12 | pos = SubstringMatch.bruteforce(s, t); 13 | } 14 | int endTime = new DateTime.now().millisecondsSinceEpoch; 15 | 16 | double time = (endTime - startTime) / 1000.0; 17 | 18 | print(startTime); 19 | print(endTime); 20 | if(s.indexOf(t) != pos) 21 | throw new Exception(name + " failed"); 22 | print("$name : res = $pos, time = $time s"); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /dart/25-GraphBascis/AdjList.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图的邻接表 6 | */ 7 | class AdjList{ 8 | int? _V;//图的顶点数量 9 | int? _E;//图的边的数量 10 | List? _adj;//邻接矩阵 11 | 12 | AdjList( V,E,List list) { 13 | _V = V; 14 | _E = E ; 15 | if(V < 0) throw Exception("V must be non-negative"); 16 | if(E < 0) throw Exception("E must be non-negative"); 17 | _adj = List.generate(V, (_)=> LinkedList>(),growable: false); 18 | for(int i =1;i<=E;i++){ 19 | int a = int.parse(list[i].split(" ")[0]); 20 | _validateVertex(a); 21 | int b = int.parse(list[i].split(" ")[1]); 22 | _validateVertex(b); 23 | var currentLinkedEntryA = LinkedListEntryImpl(a); 24 | var currentLinkedEntryB = LinkedListEntryImpl(b); 25 | 26 | _adj![a].add(currentLinkedEntryB); 27 | _adj![b].add(currentLinkedEntryA); 28 | } 29 | } 30 | 31 | _validateVertex(int v){ 32 | if(v < 0 || v >= _V!) 33 | throw new Exception("vertex $v is invalid"); 34 | } 35 | 36 | int? V(){ 37 | return _V; 38 | } 39 | 40 | bool hasEdge(int v, int w){ 41 | _validateVertex(v); 42 | _validateVertex(w); 43 | return (_adj![v] as LinkedList).contains(w); 44 | } 45 | 46 | int _degree(int v){ 47 | return _adj![v].length; 48 | } 49 | 50 | int? E(){ 51 | return _E; 52 | } 53 | 54 | adj(int v){ 55 | _validateVertex(v); 56 | return _adj![v]; 57 | } 58 | 59 | @override 60 | String toString() { 61 | 62 | StringBuffer sb = new StringBuffer(); 63 | sb.write("V = $_V, E = $_E\n"); 64 | for (int i = 0; i < _V!; i ++) { 65 | sb.write("节点: $i "); 66 | sb.write("${(_adj![i] as LinkedList).toString()} "); 67 | sb.write('\n'); 68 | } 69 | return sb.toString(); 70 | } 71 | } 72 | 73 | void main() async { 74 | File content = File("g.txt"); 75 | List list = await content.readAsLines(); 76 | //读取到文件的顶点数量以及 77 | print(list[0].split(" ")[0]); 78 | print(list[0].split(" ")[1]); 79 | int v = int.parse(list[0].split(" ")[0]) ; 80 | int e = int.parse(list[0].split(" ")[1]) ; 81 | // 82 | AdjList adjList= AdjList(v, e, list); 83 | print(adjList); 84 | 85 | } 86 | class LinkedListEntryImpl extends LinkedListEntry> { 87 | 88 | final int value; 89 | 90 | LinkedListEntryImpl(this.value); 91 | 92 | @override 93 | String toString() { 94 | return "value is $value"; 95 | } 96 | } -------------------------------------------------------------------------------- /dart/25-GraphBascis/AdjMatrix.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | /** 4 | * 图的邻接矩阵表示方式 5 | * 6 | * 注: 7 | * 先读取文件,将相应数据赋值 8 | */ 9 | class AdjMatrix { 10 | int? _V;//图的顶点数量 11 | int? _E;//图的边的数量 12 | List? _adj;//邻接矩阵 13 | 14 | 15 | AdjMatrix( V,E,List list) { 16 | _V = V; 17 | _E = E ; 18 | if(V < 0) throw Exception("V must be non-negative"); 19 | if(E < 0) throw Exception("E must be non-negative"); 20 | _adj = List.generate(V, (_)=>List.generate(V,(_)=> 0),growable: false); 21 | for(int i =1;i<=E;i++){ 22 | int a = int.parse(list[i].split(" ")[0]); 23 | _validateVertex(a); 24 | int b = int.parse(list[i].split(" ")[1]); 25 | _validateVertex(b); 26 | _adj![a][b] = 1; 27 | _adj![b][a] = 1; 28 | } 29 | } 30 | 31 | _validateVertex(int v){ 32 | if(v < 0 || v >= _V!) 33 | throw new Exception("vertex $v is invalid"); 34 | } 35 | 36 | int? V(){ 37 | return _V; 38 | } 39 | 40 | bool hasEdge(int v, int w){ 41 | _validateVertex(v); 42 | _validateVertex(w); 43 | return _adj![v][w] == 1; 44 | } 45 | 46 | int _degree(int v){ 47 | return _adj![v].length; 48 | } 49 | 50 | int? E(){ 51 | return _E; 52 | } 53 | 54 | List adj(int v){ 55 | _validateVertex(v); 56 | List res = List.filled(_V!, 0,growable: true); 57 | for(int i = 0; i < _V!; i ++) 58 | if(_adj![v][i] == 1) 59 | res.add(i); 60 | return res; 61 | } 62 | 63 | @override 64 | String toString() { 65 | StringBuffer sb = new StringBuffer(); 66 | sb.write("V = $_V, E = $_E\n"); 67 | for (int i = 0; i < _V!; i ++) { 68 | for (int j = 0; j < _V!; j ++) 69 | sb.write("${_adj![i][j]} "); 70 | sb.write('\n'); 71 | } 72 | return sb.toString(); 73 | } 74 | 75 | 76 | } 77 | 78 | void main() async { 79 | File content = File("g.txt"); 80 | List list = await content.readAsLines(); 81 | //读取到文件的顶点数量以及 82 | print(list[0].split(" ")[0]); 83 | print(list[0].split(" ")[1]); 84 | int v = int.parse(list[0].split(" ")[0]) ; 85 | int e = int.parse(list[0].split(" ")[1]) ; 86 | // 87 | AdjMatrix adjMatrix = AdjMatrix(v, e, list); 88 | print(adjMatrix); 89 | 90 | } -------------------------------------------------------------------------------- /dart/25-GraphBascis/AdjSet.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图的邻接表 6 | * 7 | */ 8 | class AdjSet { 9 | int? _V; //图的顶点数量 10 | int? _E; //图的边的数量 11 | List? _treeSet; 12 | 13 | AdjSet(V, E, List list) { 14 | _V = V; 15 | _E = E; 16 | if (V < 0) throw Exception("V must be non-negative"); 17 | if (E < 0) throw Exception("E must be non-negative"); 18 | _treeSet = List.generate(V, (_) => SplayTreeSet(), growable: false); 19 | 20 | for (int i = 1; i <= E; i++) { 21 | int a = int.parse(list[i].split(" ")[0]); 22 | _validateVertex(a); 23 | int b = int.parse(list[i].split(" ")[1]); 24 | _validateVertex(b); 25 | (_treeSet![a] as SplayTreeSet).add(b); 26 | (_treeSet![b] as SplayTreeSet).add(a); 27 | } 28 | } 29 | 30 | _validateVertex(int v) { 31 | if (v < 0 || v >= _V!) throw new Exception("vertex $v is invalid"); 32 | } 33 | 34 | int? V() { 35 | return _V; 36 | } 37 | 38 | bool hasEdge(int v, int w) { 39 | _validateVertex(v); 40 | _validateVertex(w); 41 | return (_treeSet![v] as SplayTreeSet).elementAt(w) == 1; 42 | } 43 | 44 | int _degree(int v) { 45 | return _treeSet![v].length; 46 | } 47 | 48 | int? E() { 49 | return _E; 50 | } 51 | 52 | adj(int v) { 53 | _validateVertex(v); 54 | return _treeSet![v]; 55 | } 56 | 57 | @override 58 | String toString() { 59 | StringBuffer sb = new StringBuffer(); 60 | sb.write("V = $_V, E = $_E\n"); 61 | for (int j = 0; j < _V!; j++) { 62 | sb.write("节点:$j "); 63 | sb.write("${_treeSet![j].toString()} "); 64 | sb.write('\n'); 65 | } 66 | return sb.toString(); 67 | } 68 | } 69 | 70 | void main() async { 71 | File content = File("g.txt"); 72 | List list = await content.readAsLines(); 73 | //读取到文件的顶点数量以及 74 | print(list[0].split(" ")[0]); 75 | print(list[0].split(" ")[1]); 76 | int v = int.parse(list[0].split(" ")[0]); 77 | int e = int.parse(list[0].split(" ")[1]); 78 | // 79 | AdjSet adjList = AdjSet(v, e, list); 80 | print(adjList); 81 | } 82 | -------------------------------------------------------------------------------- /dart/25-GraphBascis/FileOperator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | /** 5 | * 文件操作类 6 | */ 7 | class FileOperator{ 8 | 9 | static Future getFileString(String filename) async{ 10 | Stream> content = File(filename).openRead(); 11 | List lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList(); 12 | var words = []; 13 | for(int i = 0;i element == ""); 17 | return words; 18 | } 19 | } -------------------------------------------------------------------------------- /dart/25-GraphBascis/Graph.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | class Graph{ 4 | int? _V; //图的顶点数量 5 | int? _E; //图的边的数量 6 | List? _treeSet; 7 | 8 | Graph(V, E, List list) { 9 | _V = V; 10 | _E = E; 11 | if (V < 0) throw Exception("V must be non-negative"); 12 | if (E < 0) throw Exception("E must be non-negative"); 13 | _treeSet = List.generate(V, (_) => SplayTreeSet(), growable: false); 14 | 15 | for (int i = 1; i <= E; i++) { 16 | int a = int.parse(list[i].split(" ")[0]); 17 | _validateVertex(a); 18 | int b = int.parse(list[i].split(" ")[1]); 19 | _validateVertex(b); 20 | (_treeSet![a] as SplayTreeSet).add(b); 21 | (_treeSet![b] as SplayTreeSet).add(a); 22 | } 23 | } 24 | 25 | _validateVertex(int v) { 26 | if (v < 0 || v >= _V!) throw new Exception("vertex $v is invalid"); 27 | } 28 | 29 | int? V() { 30 | return _V; 31 | } 32 | 33 | bool hasEdge(int v, int w) { 34 | _validateVertex(v); 35 | _validateVertex(w); 36 | return (_treeSet![v] as SplayTreeSet).contains(w); 37 | } 38 | 39 | int _degree(int v) { 40 | return _treeSet![v].length; 41 | } 42 | 43 | int? E() { 44 | return _E; 45 | } 46 | 47 | adj(int v) { 48 | _validateVertex(v); 49 | return _treeSet![v]; 50 | } 51 | 52 | @override 53 | String toString() { 54 | StringBuffer sb = new StringBuffer(); 55 | sb.write("V = $_V, E = $_E\n"); 56 | for (int j = 0; j < _V!; j++) { 57 | sb.write("节点:$j "); 58 | sb.write("${_treeSet![j].toString()} "); 59 | sb.write('\n'); 60 | } 61 | return sb.toString(); 62 | } 63 | } 64 | void main() async { 65 | File content = File("g.txt"); 66 | List list = await content.readAsLines(); 67 | //读取到文件的顶点数量以及 68 | print(list[0].split(" ")[0]); 69 | print(list[0].split(" ")[1]); 70 | int v = int.parse(list[0].split(" ")[0]) ; 71 | int e = int.parse(list[0].split(" ")[1]) ; 72 | // 73 | Graph adjList= Graph(v, e, list); 74 | print(adjList); 75 | 76 | } 77 | -------------------------------------------------------------------------------- /dart/25-GraphBascis/ListItem.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | class LinkedListEntryImpl extends LinkedListEntry> { 4 | final int value; 5 | 6 | LinkedListEntryImpl(this.value); 7 | 8 | @override 9 | String toString() { 10 | return "value is $value"; 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /dart/25-GraphBascis/g.txt: -------------------------------------------------------------------------------- 1 | 7 6 2 | 0 1 3 | 0 2 4 | 1 3 5 | 1 4 6 | 2 3 7 | 2 6 -------------------------------------------------------------------------------- /dart/26-GraphDFS/AdjMatrix.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | /** 4 | * 图的邻接矩阵表示方式 5 | * 6 | * 注: 7 | * 先读取文件,将相应数据赋值 8 | */ 9 | class AdjMatrix { 10 | int? _V;//图的顶点数量 11 | int? _E;//图的边的数量 12 | List? _adj;//邻接矩阵 13 | 14 | 15 | AdjMatrix( V,E,List list) { 16 | _V = V; 17 | _E = E ; 18 | if(V < 0) throw Exception("V must be non-negative"); 19 | if(E < 0) throw Exception("E must be non-negative"); 20 | _adj = List.generate(V, (_)=>List.generate(V,(_)=> 0),growable: false); 21 | for(int i =1;i<=E;i++){ 22 | int a = int.parse(list[i].split(" ")[0]); 23 | _validateVertex(a); 24 | int b = int.parse(list[i].split(" ")[1]); 25 | _validateVertex(b); 26 | _adj![a][b] = 1; 27 | _adj![b][a] = 1; 28 | } 29 | } 30 | 31 | _validateVertex(int v){ 32 | if(v < 0 || v >= _V!) 33 | throw new Exception("vertex $v is invalid"); 34 | } 35 | 36 | int? V(){ 37 | return _V; 38 | } 39 | 40 | bool hasEdge(int v, int w){ 41 | _validateVertex(v); 42 | _validateVertex(w); 43 | return _adj![v][w] == 1; 44 | } 45 | 46 | int _degree(int v){ 47 | return _adj![v].length; 48 | } 49 | 50 | int? E(){ 51 | return _E; 52 | } 53 | 54 | List adj(int v){ 55 | _validateVertex(v); 56 | List res = List.filled(_V!, 0,growable: true); 57 | for(int i = 0; i < _V!; i ++) 58 | if(_adj![v][i] == 1) 59 | res.add(i); 60 | return res; 61 | } 62 | 63 | @override 64 | String toString() { 65 | StringBuffer sb = new StringBuffer(); 66 | sb.write("V = $_V, E = $_E\n"); 67 | for (int i = 0; i < _V!; i ++) { 68 | for (int j = 0; j < _V!; j ++) 69 | sb.write("${_adj![i][j]} "); 70 | sb.write('\n'); 71 | } 72 | return sb.toString(); 73 | } 74 | 75 | 76 | } 77 | 78 | void main() async { 79 | File content = File("g.txt"); 80 | List list = await content.readAsLines(); 81 | //读取到文件的顶点数量以及 82 | print(list[0].split(" ")[0]); 83 | print(list[0].split(" ")[1]); 84 | int v = int.parse(list[0].split(" ")[0]) ; 85 | int e = int.parse(list[0].split(" ")[1]) ; 86 | // 87 | AdjMatrix adjMatrix = AdjMatrix(v, e, list); 88 | print(adjMatrix); 89 | 90 | } -------------------------------------------------------------------------------- /dart/26-GraphDFS/AdjMatrixDFS.dart: -------------------------------------------------------------------------------- 1 | import 'AdjMatrix.dart'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 邻接矩阵的深度遍历 6 | */ 7 | class AdjMatrixDFS { 8 | AdjMatrix? G; 9 | 10 | List? visited; 11 | 12 | List? preList; 13 | 14 | List? postList; 15 | 16 | AdjMatrixDFS(AdjMatrix G) { 17 | this.G = G; 18 | visited = List.filled(G.V()!, false, growable: true); 19 | preList = List.filled(0, 0, growable: true); 20 | postList = List.filled(0, 0, growable: true); 21 | for (int v = 0; v < G.V()!; v++) { 22 | if (!(visited![v])) { 23 | _dfs(v); 24 | } 25 | } 26 | } 27 | 28 | _dfs(int v) { 29 | visited![v] = true; 30 | preList!.add(v); 31 | for (int w in G!.adj(v)) { 32 | if (!visited![w]) { 33 | _dfs(w); 34 | } 35 | } 36 | postList!.add(v); 37 | } 38 | 39 | pre() { 40 | return preList; 41 | } 42 | 43 | post() { 44 | return postList; 45 | } 46 | } 47 | 48 | void main() async { 49 | File content = File("g.txt"); 50 | List list = await content.readAsLines(); 51 | //读取到文件的顶点数量以及 52 | print(list[0].split(" ")[0]); 53 | print(list[0].split(" ")[1]); 54 | int v = int.parse(list[0].split(" ")[0]); 55 | int e = int.parse(list[0].split(" ")[1]); 56 | // 57 | AdjMatrix adjList = AdjMatrix(v, e, list); 58 | AdjMatrixDFS graphDFS = new AdjMatrixDFS(adjList); 59 | print("DFS preOrder : ${graphDFS.pre()}"); 60 | print("DFS postOrder : ${graphDFS.post()}"); 61 | } 62 | -------------------------------------------------------------------------------- /dart/26-GraphDFS/ArrayStack.dart: -------------------------------------------------------------------------------- 1 | import 'Stack.dart'; 2 | class ArrayStack implements Stack{ 3 | 4 | List? arr; 5 | ArrayStack(){ 6 | arr =[]; 7 | } 8 | 9 | @override 10 | int getSize() { 11 | return arr!.length; 12 | } 13 | 14 | @override 15 | bool isEmpty() { 16 | return arr!.isEmpty; 17 | } 18 | 19 | @override 20 | T peek() { 21 | return arr![0]; 22 | } 23 | 24 | @override 25 | T pop() => arr!.removeLast(); 26 | 27 | @override 28 | void push(T e) { 29 | arr!.add(e); 30 | } 31 | 32 | @override 33 | String toString() { 34 | StringBuffer buffer = new StringBuffer(); 35 | buffer.write("Stack: "); 36 | buffer.write('['); 37 | for(int i = 0 ; i < arr!.length ; i ++){ 38 | buffer.write(arr![i]); 39 | if(i != arr!.length - 1) 40 | buffer.write(", "); 41 | } 42 | buffer.write("] top"); 43 | return buffer.toString(); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /dart/26-GraphDFS/Graph.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图 6 | */ 7 | class Graph{ 8 | int? _V; //图的顶点数量 9 | int? _E; //图的边的数量 10 | List? _treeSet; 11 | 12 | Graph(V, E, List list) { 13 | _V = V; 14 | _E = E; 15 | if (V < 0) throw Exception("V must be non-negative"); 16 | if (E < 0) throw Exception("E must be non-negative"); 17 | _treeSet = List.generate(V, (_) => SplayTreeSet(), growable: false); 18 | 19 | for (int i = 1; i <= E; i++) { 20 | int a = int.parse(list[i].split(" ")[0]); 21 | _validateVertex(a); 22 | int b = int.parse(list[i].split(" ")[1]); 23 | _validateVertex(b); 24 | (_treeSet![a] as SplayTreeSet).add(b); 25 | (_treeSet![b] as SplayTreeSet).add(a); 26 | } 27 | } 28 | 29 | _validateVertex(int v) { 30 | if (v < 0 || v >= _V!) throw new Exception("vertex $v is invalid"); 31 | } 32 | 33 | int? V() { 34 | return _V; 35 | } 36 | 37 | bool hasEdge(int v, int w) { 38 | _validateVertex(v); 39 | _validateVertex(w); 40 | return (_treeSet![v] as SplayTreeSet).contains(w); 41 | } 42 | 43 | int _degree(int v) { 44 | return _treeSet![v].length; 45 | } 46 | 47 | int? E() { 48 | return _E; 49 | } 50 | 51 | adj(int v) { 52 | _validateVertex(v); 53 | return _treeSet![v]; 54 | } 55 | 56 | @override 57 | String toString() { 58 | StringBuffer sb = new StringBuffer(); 59 | sb.write("V = $_V, E = $_E\n"); 60 | for (int j = 0; j < _V!; j++) { 61 | sb.write("节点:$j "); 62 | sb.write("${_treeSet![j].toString()} "); 63 | sb.write('\n'); 64 | } 65 | return sb.toString(); 66 | } 67 | } 68 | void main() async { 69 | File content = File("g.txt"); 70 | List list = await content.readAsLines(); 71 | //读取到文件的顶点数量以及 72 | print(list[0].split(" ")[0]); 73 | print(list[0].split(" ")[1]); 74 | int v = int.parse(list[0].split(" ")[0]) ; 75 | int e = int.parse(list[0].split(" ")[1]) ; 76 | // 77 | Graph adjList= Graph(v, e, list); 78 | print(adjList); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /dart/26-GraphDFS/GraphDFS.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图的深度遍历 6 | */ 7 | class GraphDFS { 8 | Graph? G; 9 | 10 | List? visited; 11 | 12 | List? preList; 13 | 14 | List? postList; 15 | 16 | GraphDFS(Graph G) { 17 | this.G = G; 18 | visited = List.filled(G.V()!, false, growable: true); 19 | preList = List.filled(0, 0, growable: true); 20 | postList = List.filled(0, 0, growable: true); 21 | for (int v = 0; v < G.V()!; v++) { 22 | if (!(visited![v])) { 23 | _dfs(v); 24 | } 25 | } 26 | } 27 | 28 | _dfs(int v) { 29 | visited![v] = true; 30 | preList!.add(v); 31 | for (int w in G!.adj(v)) { 32 | if (!visited![w]) { 33 | _dfs(w); 34 | } 35 | } 36 | postList!.add(v); 37 | } 38 | 39 | pre() { 40 | return preList; 41 | } 42 | 43 | post() { 44 | return postList; 45 | } 46 | } 47 | 48 | void main() async { 49 | File content = File("g.txt"); 50 | List list = await content.readAsLines(); 51 | //读取到文件的顶点数量以及 52 | print(list[0].split(" ")[0]); 53 | print(list[0].split(" ")[1]); 54 | int v = int.parse(list[0].split(" ")[0]); 55 | int e = int.parse(list[0].split(" ")[1]); 56 | // 57 | Graph adjList = Graph(v, e, list); 58 | GraphDFS graphDFS = new GraphDFS(adjList); 59 | print("DFS preOrder : ${graphDFS.pre()}" ); 60 | print("DFS postOrder : ${graphDFS.post()}"); 61 | } 62 | -------------------------------------------------------------------------------- /dart/26-GraphDFS/GraphDFSnr.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | import 'Stack.dart'; 4 | import 'ArrayStack.dart'; 5 | 6 | class GraphDFSnr { 7 | Graph? G; 8 | 9 | List? visited; 10 | 11 | List? preList; 12 | 13 | GraphDFSnr(Graph G) { 14 | this.G = G; 15 | visited = List.filled(G.V()!, false, growable: true); 16 | preList = List.filled(0, 0, growable: true); 17 | for (int v = 0; v < G.V()!; v++) { 18 | if (!(visited![v])) { 19 | _dfs(v); 20 | } 21 | } 22 | } 23 | 24 | _dfs(int v) { 25 | ArrayStack stack = ArrayStack(); 26 | stack.push(v); 27 | visited![v] = true; 28 | while (!stack.isEmpty()) { 29 | int cur = stack.pop(); 30 | preList!.add(cur); 31 | for (int w in G!.adj(cur)) 32 | if (!visited![w]) { 33 | stack.push(w); 34 | visited![w] = true; 35 | } 36 | } 37 | } 38 | 39 | pre() { 40 | return preList; 41 | } 42 | } 43 | 44 | void main() async { 45 | File content = File("g.txt"); 46 | List list = await content.readAsLines(); 47 | //读取到文件的顶点数量以及 48 | print(list[0].split(" ")[0]); 49 | print(list[0].split(" ")[1]); 50 | int v = int.parse(list[0].split(" ")[0]); 51 | int e = int.parse(list[0].split(" ")[1]); 52 | // 53 | Graph adjList = Graph(v, e, list); 54 | GraphDFSnr graphDFS = new GraphDFSnr(adjList); 55 | print("DFS preOrder : ${graphDFS.pre()}"); 56 | } 57 | -------------------------------------------------------------------------------- /dart/26-GraphDFS/Stack.dart: -------------------------------------------------------------------------------- 1 | abstract class Stack{ 2 | int getSize(); 3 | bool isEmpty(); 4 | void push(T e); 5 | T pop(); 6 | T peek(); 7 | } -------------------------------------------------------------------------------- /dart/26-GraphDFS/g.txt: -------------------------------------------------------------------------------- 1 | 7 6 2 | 0 1 3 | 0 2 4 | 1 3 5 | 1 4 6 | 2 3 7 | 2 6 -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/BipartitionDetection.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | /** 4 | * 二分图检测 5 | */ 6 | class BipartitionDetection { 7 | Graph? _G; 8 | 9 | List? _visited; 10 | 11 | List? _colors; 12 | 13 | bool _isBipartite = true; 14 | 15 | BipartitionDetection(Graph G) { 16 | this._G = G; 17 | _visited = List.filled(_G!.V()!, false, growable: true); 18 | _colors = List.filled(_G!.V()!, 0, growable: true); 19 | for (int i = 0; i < _G!.V()!; i++) _colors![i] = -1; 20 | 21 | for (int v = 0; v < _G!.V()!; v++) 22 | if (!_visited![v]) if (!_dfs(v, 0)) { 23 | _isBipartite = false; 24 | break; 25 | } 26 | } 27 | 28 | bool _dfs(int v, int color) { 29 | _visited![v] = true; 30 | _colors![v] = color; 31 | for (int w in _G!.adj(v)) 32 | if (!_visited![w]) { 33 | if (!_dfs(w, 1 - color)) return false; 34 | } else if (_colors![w] == _colors![v]) return false; 35 | return true; 36 | } 37 | 38 | bool isBipartite() { 39 | return _isBipartite; 40 | } 41 | } 42 | void main()async{ 43 | print("------------------txt1"); 44 | File content = File("g.txt"); 45 | List list = await content.readAsLines(); 46 | //读取到文件的顶点数量以及 47 | int v = int.parse(list[0].split(" ")[0]); 48 | int e = int.parse(list[0].split(" ")[1]); 49 | // 50 | Graph graph = Graph(v, e, list); 51 | 52 | BipartitionDetection bipartitionDetection = BipartitionDetection(graph); 53 | print(bipartitionDetection.isBipartite()); 54 | print("------------------txt2"); 55 | File content2 = File("g2.txt"); 56 | List list2 = await content2.readAsLines(); 57 | //读取到文件的顶点数量以及 58 | int v2 = int.parse(list2[0].split(" ")[0]); 59 | int e2 = int.parse(list2[0].split(" ")[1]); 60 | // 61 | Graph graph2 = Graph(v2, e2, list2); 62 | 63 | BipartitionDetection bipartitionDetection2 = BipartitionDetection(graph2); 64 | print(bipartitionDetection2.isBipartite()); 65 | print("------------------txt3"); 66 | 67 | File content3 = File("g3.txt"); 68 | List list3 = await content3.readAsLines(); 69 | //读取到文件的顶点数量以及 70 | int v3 = int.parse(list3[0].split(" ")[0]); 71 | int e3 = int.parse(list3[0].split(" ")[1]); 72 | // 73 | Graph graph3 = Graph(v3, e3, list3); 74 | 75 | BipartitionDetection bipartitionDetection3 = BipartitionDetection(graph3); 76 | print(bipartitionDetection3.isBipartite()); 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/CC.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图的联通分量 6 | */ 7 | class CC{ 8 | Graph? G; 9 | 10 | List? _visited; 11 | int _cccount = 0; 12 | 13 | CC(Graph G) { 14 | this.G = G; 15 | _visited = List.filled(G.V()!, 0, growable: true); 16 | 17 | for(int i = 0; i < _visited!.length; i ++) 18 | _visited![i] = -1; 19 | 20 | for (int v = 0; v < G.V()!; v++) { 21 | if (_visited![v] == -1) { 22 | _dfs(v,_cccount); 23 | _cccount ++; 24 | } 25 | } 26 | } 27 | 28 | _dfs(int v, int ccid) { 29 | _visited![v] = ccid; 30 | for (int w in G!.adj(v)) { 31 | if (_visited![w] == -1) { 32 | _dfs(w,ccid); 33 | } 34 | } 35 | } 36 | 37 | int count(){ 38 | return _cccount; 39 | } 40 | 41 | bool isConnected(int v, int w){ 42 | G!.validateVertex(v); 43 | G!.validateVertex(w); 44 | return _visited![v] == _visited![w]; 45 | } 46 | 47 | components(){ 48 | List? res =List.generate(_cccount, (_)=>List.generate(0,(_)=> 0),growable: true); 49 | for(int v = 0; v < G!.V()!; v ++) 50 | res[_visited![v]].add(v); 51 | return res; 52 | } 53 | } 54 | 55 | void main() async { 56 | File content = File("g.txt"); 57 | List list = await content.readAsLines(); 58 | //读取到文件的顶点数量以及 59 | int v = int.parse(list[0].split(" ")[0]) ; 60 | int e = int.parse(list[0].split(" ")[1]) ; 61 | // 62 | Graph adjList= Graph(v, e, list); 63 | CC cc = new CC(adjList); 64 | print(cc.count()); 65 | 66 | print(cc.isConnected(0, 6)); 67 | print(cc.isConnected(5, 6)); 68 | 69 | List comp = cc.components(); 70 | for(int ccid = 0; ccid < comp.length; ccid ++){ 71 | print("$ccid :: "); 72 | for(int w in comp[ccid]) { 73 | print("$w "); 74 | } 75 | print(""); 76 | } 77 | 78 | print(adjList); 79 | 80 | } -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/CycleDetection.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | /** 4 | * 无向图的环检测 5 | */ 6 | class CycleDetection { 7 | Graph? _G; 8 | 9 | List? _visited; 10 | 11 | bool _hasCycle = false; 12 | 13 | CycleDetection(Graph G) { 14 | this._G = G; 15 | _visited = List.filled(_G!.V()!, false, growable: true); 16 | for (int v = 0; v < _G!.V()!; v++) 17 | if (!_visited![v]) if (_dfs(v, v)) { 18 | _hasCycle = true; 19 | break; 20 | } 21 | } 22 | 23 | // 从顶点 v 开始,判断图中是否有环 24 | bool _dfs(int v, int parent) { 25 | _visited![v] = true; 26 | for (int w in _G!.adj(v)) 27 | if (!_visited![w]) { 28 | if (_dfs(w, v)) return true; 29 | } else if (w != parent) return true; 30 | return false; 31 | } 32 | 33 | bool hasCycle() { 34 | return _hasCycle; 35 | } 36 | } 37 | 38 | void main () async{ 39 | 40 | File content = File("g.txt"); 41 | List list = await content.readAsLines(); 42 | //读取到文件的顶点数量以及 43 | int v = int.parse(list[0].split(" ")[0]); 44 | int e = int.parse(list[0].split(" ")[1]); 45 | // 46 | Graph graph = Graph(v, e, list); 47 | 48 | CycleDetection cycleDetection = CycleDetection(graph); 49 | print(cycleDetection.hasCycle()); 50 | 51 | File content2 = File("g2.txt"); 52 | List list2 = await content2.readAsLines(); 53 | //读取到文件的顶点数量以及 54 | int v2 = int.parse(list2[0].split(" ")[0]); 55 | int e2 = int.parse(list2[0].split(" ")[1]); 56 | // 57 | Graph graph2 = Graph(v2, e2, list2); 58 | 59 | CycleDetection cycleDetection2 = CycleDetection(graph2); 60 | print(cycleDetection2.hasCycle()); 61 | 62 | 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/Graph.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图 6 | */ 7 | class Graph{ 8 | int? _V; //图的顶点数量 9 | int? _E; //图的边的数量 10 | List? _treeSet; 11 | 12 | Graph(V, E, List list) { 13 | _V = V; 14 | _E = E; 15 | if (V < 0) throw Exception("V must be non-negative"); 16 | if (E < 0) throw Exception("E must be non-negative"); 17 | _treeSet = List.generate(V, (_) => SplayTreeSet(), growable: false); 18 | 19 | for (int i = 1; i <= E; i++) { 20 | int a = int.parse(list[i].split(" ")[0]); 21 | validateVertex(a); 22 | int b = int.parse(list[i].split(" ")[1]); 23 | validateVertex(b); 24 | (_treeSet![a] as SplayTreeSet).add(b); 25 | (_treeSet![b] as SplayTreeSet).add(a); 26 | } 27 | } 28 | 29 | validateVertex(int v) { 30 | if (v < 0 || v >= _V!) throw new Exception("vertex $v is invalid"); 31 | } 32 | 33 | int? V() { 34 | return _V; 35 | } 36 | 37 | bool hasEdge(int v, int w) { 38 | validateVertex(v); 39 | validateVertex(w); 40 | return (_treeSet![v] as SplayTreeSet).contains(w); 41 | } 42 | 43 | int _degree(int v) { 44 | return _treeSet![v].length; 45 | } 46 | 47 | int? E() { 48 | return _E; 49 | } 50 | 51 | adj(int v) { 52 | validateVertex(v); 53 | return _treeSet![v]; 54 | } 55 | 56 | @override 57 | String toString() { 58 | StringBuffer sb = new StringBuffer(); 59 | sb.write("V = $_V, E = $_E\n"); 60 | for (int j = 0; j < _V!; j++) { 61 | sb.write("节点:$j "); 62 | sb.write("${_treeSet![j].toString()} "); 63 | sb.write('\n'); 64 | } 65 | return sb.toString(); 66 | } 67 | } 68 | void main() async { 69 | File content = File("g.txt"); 70 | List list = await content.readAsLines(); 71 | //读取到文件的顶点数量以及 72 | print(list[0].split(" ")[0]); 73 | print(list[0].split(" ")[1]); 74 | int v = int.parse(list[0].split(" ")[0]) ; 75 | int e = int.parse(list[0].split(" ")[1]) ; 76 | // 77 | Graph adjList= Graph(v, e, list); 78 | print(adjList); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/GraphDFS.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图的深度遍历 6 | */ 7 | class GraphDFS { 8 | Graph? G; 9 | 10 | List? _visited; 11 | 12 | List? _preList; 13 | 14 | List? _postList; 15 | 16 | GraphDFS(Graph G) { 17 | this.G = G; 18 | _visited = List.filled(G.V()!, false, growable: true); 19 | _preList = List.filled(0, 0, growable: true); 20 | _postList = List.filled(0, 0, growable: true); 21 | for (int v = 0; v < G.V()!; v++) { 22 | if (!(_visited![v])) { 23 | _dfs(v); 24 | } 25 | } 26 | } 27 | 28 | _dfs(int v) { 29 | _visited![v] = true; 30 | _preList!.add(v); 31 | for (int w in G!.adj(v)) { 32 | if (!_visited![w]) { 33 | _dfs(w); 34 | } 35 | } 36 | _postList!.add(v); 37 | } 38 | 39 | pre() { 40 | return _preList; 41 | } 42 | 43 | post() { 44 | return _postList; 45 | } 46 | } 47 | 48 | void main() async { 49 | File content = File("g.txt"); 50 | List list = await content.readAsLines(); 51 | //读取到文件的顶点数量以及 52 | int v = int.parse(list[0].split(" ")[0]); 53 | int e = int.parse(list[0].split(" ")[1]); 54 | // 55 | Graph adjList = Graph(v, e, list); 56 | GraphDFS graphDFS = new GraphDFS(adjList); 57 | print("DFS preOrder : ${graphDFS.pre()}" ); 58 | print("DFS postOrder : ${graphDFS.post()}"); 59 | } 60 | -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/SingleSourcePath.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | /** 4 | * 单源路径问题 5 | * 6 | */ 7 | class SingleSourcePath { 8 | Graph? _G; 9 | 10 | int? _s; 11 | 12 | List? pre; 13 | 14 | SingleSourcePath(Graph G, int s) { 15 | this._G = G; 16 | this._s = s; 17 | pre = List.filled(_G!.V()!, 0, growable: true); 18 | for (int i = 0; i < pre!.length; i++) { 19 | pre![i] = -1; 20 | } 21 | _dfs(s, s); 22 | } 23 | 24 | _dfs(int v, int parent) { 25 | pre![v] = parent; 26 | for (int w in _G!.adj(v)) { 27 | if (pre![w] == -1) { 28 | _dfs(w, v); 29 | } 30 | } 31 | } 32 | 33 | bool isConnectedTo(int t) { 34 | _G!.validateVertex(t); 35 | return pre![t] != -1; 36 | } 37 | 38 | path(int t) { 39 | List res = List.filled(0, 0, growable: true); 40 | if (!isConnectedTo(t)) return res; 41 | 42 | int cur = t; 43 | while (cur != _s) { 44 | res.add(cur); 45 | cur = pre![cur]; 46 | } 47 | res.add(_s); 48 | var result = res.reversed; 49 | return result; 50 | } 51 | } 52 | 53 | void main() async { 54 | File content = File("g.txt"); 55 | List list = await content.readAsLines(); 56 | //读取到文件的顶点数量以及 57 | int v = int.parse(list[0].split(" ")[0]) ; 58 | int e = int.parse(list[0].split(" ")[1]) ; 59 | // 60 | Graph graph= Graph(v, e, list); 61 | SingleSourcePath sspath = new SingleSourcePath(graph, 0); 62 | 63 | print("0 -> 6 : ${sspath.path(6)}"); 64 | print("0 -> 5 : ${sspath.path(5)}"); 65 | } 66 | -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/g.txt: -------------------------------------------------------------------------------- 1 | 7 6 2 | 0 1 3 | 0 2 4 | 1 3 5 | 1 4 6 | 2 3 7 | 2 6 -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/g2.txt: -------------------------------------------------------------------------------- 1 | 7 5 2 | 0 1 3 | 0 2 4 | 1 3 5 | 1 4 6 | 2 6 7 | -------------------------------------------------------------------------------- /dart/27-GraphDFS-Application/g3.txt: -------------------------------------------------------------------------------- 1 | 4 4 2 | 0 1 3 | 0 3 4 | 1 2 5 | 2 3 -------------------------------------------------------------------------------- /dart/28-Graph-BFS/BipartitionDetection.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | import 'dart:collection'; 4 | 5 | /** 6 | * 二分图检测BFS方法 7 | */ 8 | class BipartitionDetection { 9 | Graph? _G; 10 | 11 | List? _visited; 12 | 13 | List? _colors; 14 | 15 | bool _isBipartite = true; 16 | 17 | BipartitionDetection(Graph G) { 18 | this._G = G; 19 | _visited = List.filled(_G!.V()!, false, growable: true); 20 | _colors = List.filled(_G!.V()!, 0, growable: true); 21 | for (int i = 0; i < _G!.V()!; i++) _colors![i] = -1; 22 | 23 | for (int v = 0; v < _G!.V()!; v++) 24 | if (!_visited![v]) if (!_bfs(v, 0)) { 25 | _isBipartite = false; 26 | break; 27 | } 28 | } 29 | 30 | bool _bfs(int v, int color) { 31 | ListQueue queue = ListQueue(); 32 | queue.add(v); 33 | _visited![v] = true; 34 | _colors![v] = 0; 35 | while (!queue.isEmpty) { 36 | int v = queue.removeFirst(); 37 | 38 | for (int w in _G!.adj(v)) 39 | if (!_visited![w]) { 40 | queue.add(w); 41 | _visited![w] = true; 42 | _colors![w] = 1 - _colors![v]; 43 | } else if (_colors![v] == _colors![w]) return false; 44 | } 45 | return true; 46 | } 47 | 48 | bool isBipartite() { 49 | return _isBipartite; 50 | } 51 | } 52 | 53 | void main() async { 54 | print("------------------txt1"); 55 | File content = File("g.txt"); 56 | List list = await content.readAsLines(); 57 | //读取到文件的顶点数量以及 58 | int v = int.parse(list[0].split(" ")[0]); 59 | int e = int.parse(list[0].split(" ")[1]); 60 | // 61 | Graph graph = Graph(v, e, list); 62 | 63 | BipartitionDetection bipartitionDetection = BipartitionDetection(graph); 64 | print(bipartitionDetection.isBipartite()); 65 | print("------------------txt2"); 66 | File content2 = File("g2.txt"); 67 | List list2 = await content2.readAsLines(); 68 | //读取到文件的顶点数量以及 69 | int v2 = int.parse(list2[0].split(" ")[0]); 70 | int e2 = int.parse(list2[0].split(" ")[1]); 71 | // 72 | Graph graph2 = Graph(v2, e2, list2); 73 | 74 | BipartitionDetection bipartitionDetection2 = BipartitionDetection(graph2); 75 | print(bipartitionDetection2.isBipartite()); 76 | print("------------------txt3"); 77 | 78 | File content3 = File("g3.txt"); 79 | List list3 = await content3.readAsLines(); 80 | //读取到文件的顶点数量以及 81 | int v3 = int.parse(list3[0].split(" ")[0]); 82 | int e3 = int.parse(list3[0].split(" ")[1]); 83 | // 84 | Graph graph3 = Graph(v3, e3, list3); 85 | 86 | BipartitionDetection bipartitionDetection3 = BipartitionDetection(graph3); 87 | print(bipartitionDetection3.isBipartite()); 88 | } 89 | -------------------------------------------------------------------------------- /dart/28-Graph-BFS/CC.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | import 'dart:collection'; 4 | 5 | /** 6 | * 图的联通分量BFS 7 | */ 8 | class CC { 9 | Graph? _G; 10 | 11 | List? _visited; 12 | 13 | int _cccount = 0; 14 | 15 | CC(Graph G) { 16 | this._G = G; 17 | _visited = List.filled(G.V()!, 0, growable: true); 18 | 19 | for (int i = 0; i < _visited!.length; i++) _visited![i] = -1; 20 | 21 | for (int v = 0; v < G.V()!; v++) { 22 | if (_visited![v] == -1) { 23 | _bfs(v, _cccount); 24 | _cccount++; 25 | } 26 | } 27 | } 28 | 29 | _bfs(int v, int ccid) { 30 | ListQueue queue = ListQueue(); 31 | queue.add(v); 32 | _visited![v] = ccid; 33 | while (!queue.isEmpty) { 34 | int v = queue.removeFirst(); 35 | 36 | for (int w in _G!.adj(v)) { 37 | if (_visited![w] == -1) { 38 | queue.add(w); 39 | _visited![w] = ccid; 40 | } 41 | } 42 | } 43 | } 44 | 45 | int count() { 46 | return _cccount; 47 | } 48 | 49 | bool isConnected(int v, int w) { 50 | _G!.validateVertex(v); 51 | _G!.validateVertex(w); 52 | return _visited![v] == _visited![w]; 53 | } 54 | 55 | components() { 56 | List? res = List.generate(_cccount, (_) => List.generate(0, (_) => 0), 57 | growable: true); 58 | for (int v = 0; v < _G!.V()!; v++) res[_visited![v]].add(v); 59 | return res; 60 | } 61 | } 62 | 63 | void main() async { 64 | File content = File("g.txt"); 65 | List list = await content.readAsLines(); 66 | //读取到文件的顶点数量以及 67 | int v = int.parse(list[0].split(" ")[0]); 68 | int e = int.parse(list[0].split(" ")[1]); 69 | // 70 | Graph adjList = Graph(v, e, list); 71 | CC cc = new CC(adjList); 72 | print(cc.count()); 73 | 74 | print(cc.isConnected(0, 6)); 75 | print(cc.isConnected(5, 6)); 76 | 77 | List comp = cc.components(); 78 | for (int ccid = 0; ccid < comp.length; ccid++) { 79 | print("$ccid :: "); 80 | for (int w in comp[ccid]) { 81 | print("$w "); 82 | } 83 | print(""); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /dart/28-Graph-BFS/CycleDetection.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | import 'dart:collection'; 4 | 5 | /** 6 | * 无向图的环检测BFS问题 7 | */ 8 | class CycleDetection { 9 | Graph? _G; 10 | 11 | List? _visited; 12 | 13 | bool _hasCycle = false; 14 | 15 | List? _pre; 16 | 17 | CycleDetection(Graph G) { 18 | this._G = G; 19 | _visited = List.filled(_G!.V()!, false, growable: true); 20 | _pre = List.filled(_G!.V()!, 0, growable: true); 21 | for (int i = 0; i < _G!.V()!; i++) { 22 | _pre![i] = -1; 23 | } 24 | for (int v = 0; v < _G!.V()!; v++) { 25 | if (!_visited![v]) { 26 | if (_bfs(v, v)) { 27 | _hasCycle = true; 28 | break; 29 | } 30 | } 31 | } 32 | } 33 | 34 | // 从顶点 v 开始,判断图中是否有环 35 | bool _bfs(int v, int parent) { 36 | ListQueue queue = ListQueue(); 37 | queue.add(v); 38 | _visited![v] = true; 39 | _pre![v] = v; 40 | while (!queue.isEmpty) { 41 | int v = queue.removeFirst(); 42 | 43 | for (int w in _G!.adj(v)) 44 | if (!_visited![w]) { 45 | queue.add(w); 46 | _visited![w] = true; 47 | _pre![w] = v; 48 | } else if (_pre![v] != w) return true; 49 | } 50 | 51 | return false; 52 | } 53 | 54 | bool hasCycle() { 55 | return _hasCycle; 56 | } 57 | } 58 | 59 | void main() async { 60 | File content = File("g.txt"); 61 | List list = await content.readAsLines(); 62 | //读取到文件的顶点数量以及 63 | int v = int.parse(list[0].split(" ")[0]); 64 | int e = int.parse(list[0].split(" ")[1]); 65 | // 66 | Graph graph = Graph(v, e, list); 67 | 68 | CycleDetection cycleDetection = CycleDetection(graph); 69 | print(cycleDetection.hasCycle()); 70 | 71 | File content2 = File("g2.txt"); 72 | List list2 = await content2.readAsLines(); 73 | //读取到文件的顶点数量以及 74 | int v2 = int.parse(list2[0].split(" ")[0]); 75 | int e2 = int.parse(list2[0].split(" ")[1]); 76 | // 77 | Graph graph2 = Graph(v2, e2, list2); 78 | 79 | CycleDetection cycleDetection2 = CycleDetection(graph2); 80 | print(cycleDetection2.hasCycle()); 81 | } 82 | -------------------------------------------------------------------------------- /dart/28-Graph-BFS/Graph.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图 6 | */ 7 | class Graph{ 8 | int? _V; //图的顶点数量 9 | int? _E; //图的边的数量 10 | List? _treeSet; 11 | 12 | Graph(V, E, List list) { 13 | _V = V; 14 | _E = E; 15 | if (V < 0) throw Exception("V must be non-negative"); 16 | if (E < 0) throw Exception("E must be non-negative"); 17 | _treeSet = List.generate(V, (_) => SplayTreeSet(), growable: false); 18 | 19 | for (int i = 1; i <= E; i++) { 20 | int a = int.parse(list[i].split(" ")[0]); 21 | validateVertex(a); 22 | int b = int.parse(list[i].split(" ")[1]); 23 | validateVertex(b); 24 | (_treeSet![a] as SplayTreeSet).add(b); 25 | (_treeSet![b] as SplayTreeSet).add(a); 26 | } 27 | } 28 | 29 | validateVertex(int v) { 30 | if (v < 0 || v >= _V!) throw new Exception("vertex $v is invalid"); 31 | } 32 | 33 | int? V() { 34 | return _V; 35 | } 36 | 37 | bool hasEdge(int v, int w) { 38 | validateVertex(v); 39 | validateVertex(w); 40 | return (_treeSet![v] as SplayTreeSet).contains(w); 41 | } 42 | 43 | int _degree(int v) { 44 | return _treeSet![v].length; 45 | } 46 | 47 | int? E() { 48 | return _E; 49 | } 50 | 51 | adj(int v) { 52 | validateVertex(v); 53 | return _treeSet![v]; 54 | } 55 | 56 | @override 57 | String toString() { 58 | StringBuffer sb = new StringBuffer(); 59 | sb.write("V = $_V, E = $_E\n"); 60 | for (int j = 0; j < _V!; j++) { 61 | sb.write("节点:$j "); 62 | sb.write("${_treeSet![j].toString()} "); 63 | sb.write('\n'); 64 | } 65 | return sb.toString(); 66 | } 67 | } 68 | void main() async { 69 | File content = File("g.txt"); 70 | List list = await content.readAsLines(); 71 | //读取到文件的顶点数量以及 72 | print(list[0].split(" ")[0]); 73 | print(list[0].split(" ")[1]); 74 | int v = int.parse(list[0].split(" ")[0]) ; 75 | int e = int.parse(list[0].split(" ")[1]) ; 76 | // 77 | Graph adjList= Graph(v, e, list); 78 | print(adjList); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /dart/28-Graph-BFS/GraphBFS.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:collection'; 3 | import 'dart:io'; 4 | /** 5 | * 图的广度优先遍历 6 | */ 7 | class GraphBFS { 8 | Graph? G; 9 | 10 | List? _visited; 11 | 12 | List? _orderList = List.filled(0,0, growable: true); 13 | 14 | GraphBFS(Graph G) { 15 | this.G = G; 16 | _visited = List.filled(G.V()!, false, growable: true); 17 | for (int v = 0; v < G.V()!; v++) { 18 | if (!(_visited![v])) { 19 | _bfs(v); 20 | } 21 | } 22 | } 23 | 24 | _bfs(int v) { 25 | ListQueue queue = ListQueue(); 26 | queue.add(v); 27 | _visited![v] = true; 28 | while (!queue.isEmpty) { 29 | int v = queue.removeFirst(); 30 | _orderList!.add(v); 31 | for (int w in G!.adj(v)) { 32 | if (!_visited![w]) { 33 | queue.add(w); 34 | _visited![w] = true; 35 | } 36 | } 37 | } 38 | } 39 | 40 | order() { 41 | return _orderList; 42 | } 43 | } 44 | void main() async { 45 | File content = File("g.txt"); 46 | List list = await content.readAsLines(); 47 | //读取到文件的顶点数量以及 48 | print(list[0].split(" ")[0]); 49 | print(list[0].split(" ")[1]); 50 | int v = int.parse(list[0].split(" ")[0]); 51 | int e = int.parse(list[0].split(" ")[1]); 52 | // 53 | Graph adjList = Graph(v, e, list); 54 | GraphBFS graphDFS = new GraphBFS(adjList); 55 | print("BFS Order : ${graphDFS.order()}" ); 56 | } -------------------------------------------------------------------------------- /dart/28-Graph-BFS/SingleSourcePath.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | import 'dart:collection'; 4 | 5 | /** 6 | * 单源路径BFS问题 7 | * 8 | */ 9 | class SingleSourcePath { 10 | Graph? _G; 11 | 12 | int? _s; 13 | 14 | List? pre; 15 | 16 | List? _visited; 17 | 18 | SingleSourcePath(Graph G, int s) { 19 | this._G = G; 20 | this._s = s; 21 | pre = List.filled(_G!.V()!, 0, growable: true); 22 | _visited = List.filled(G.V()!, false, growable: true); 23 | for (int i = 0; i < pre!.length; i++) { 24 | pre![i] = -1; 25 | } 26 | _bfs(s); 27 | } 28 | 29 | _bfs(int v) { 30 | ListQueue queue = ListQueue(); 31 | queue.add(v); 32 | _visited![v] = true; 33 | pre![v] = v; 34 | while (!queue.isEmpty) { 35 | int v = queue.removeFirst(); 36 | 37 | for (int w in _G!.adj(v)) 38 | if (!_visited![w]) { 39 | queue.add(w); 40 | _visited![w] = true; 41 | pre![w] = v; 42 | } 43 | } 44 | } 45 | 46 | bool isConnectedTo(int t) { 47 | _G!.validateVertex(t); 48 | return pre![t] != -1; 49 | } 50 | 51 | path(int t) { 52 | List res = List.filled(0, 0, growable: true); 53 | if (!isConnectedTo(t)) return res; 54 | 55 | int cur = t; 56 | while (cur != _s) { 57 | res.add(cur); 58 | cur = pre![cur]; 59 | } 60 | res.add(_s); 61 | var result = res.reversed; 62 | return result; 63 | } 64 | } 65 | 66 | void main() async { 67 | File content = File("g.txt"); 68 | List list = await content.readAsLines(); 69 | //读取到文件的顶点数量以及 70 | int v = int.parse(list[0].split(" ")[0]); 71 | int e = int.parse(list[0].split(" ")[1]); 72 | // 73 | Graph graph = Graph(v, e, list); 74 | SingleSourcePath sspath = new SingleSourcePath(graph, 0); 75 | 76 | print("0 -> 6 : ${sspath.path(6)}"); 77 | } 78 | -------------------------------------------------------------------------------- /dart/28-Graph-BFS/g.txt: -------------------------------------------------------------------------------- 1 | 7 6 2 | 0 1 3 | 0 2 4 | 1 3 5 | 1 4 6 | 2 3 7 | 2 6 -------------------------------------------------------------------------------- /dart/28-Graph-BFS/g2.txt: -------------------------------------------------------------------------------- 1 | 7 5 2 | 0 1 3 | 0 2 4 | 1 3 5 | 1 4 6 | 2 6 7 | -------------------------------------------------------------------------------- /dart/28-Graph-BFS/g3.txt: -------------------------------------------------------------------------------- 1 | 4 4 2 | 0 1 3 | 0 3 4 | 1 2 5 | 2 3 -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/Edge.dart: -------------------------------------------------------------------------------- 1 | class Edge { 2 | int? v, w; 3 | Edge(int v, int w){ 4 | this.v = v; 5 | this.w = w; 6 | } 7 | 8 | @override 9 | String toString(){ 10 | return ("$v-$w"); 11 | } 12 | } -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/FindCutPoints.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:collection'; 3 | import 'dart:math'; 4 | import 'dart:io'; 5 | 6 | /** 7 | * 查找割点 8 | */ 9 | class FindCutPoints { 10 | Graph? _G; 11 | 12 | List? _visited; 13 | 14 | List? _ord; 15 | 16 | List? _low; 17 | 18 | int _cnt = 0; 19 | 20 | HashSet? res; 21 | 22 | FindCutPoints(Graph G) { 23 | this._G = G; 24 | _visited = List.filled(_G!.V()!, false, growable: true); 25 | 26 | res = HashSet(); 27 | _ord = List.filled(_G!.V()!, 0, growable: true); 28 | _low = List.filled(_G!.V()!, 0, growable: true); 29 | _cnt = 0; 30 | 31 | for (int v = 0; v < _G!.V()!; v++) if (!_visited![v]) _dfs(v, v); 32 | } 33 | 34 | _dfs(int v, int parent) { 35 | _visited![v] = true; 36 | _ord![v] = _cnt; 37 | _low![v] = _ord![v]; 38 | _cnt++; 39 | 40 | int child = 0; 41 | 42 | for (int w in _G!.adj(v)) 43 | if (!_visited![w]) { 44 | _dfs(w, v); 45 | _low![v] = [(_low![v] as int), (_low![w] as int)].reduce(min); 46 | 47 | if (v != parent && _low![w] >= _ord![v]) res!.add(v); 48 | 49 | child++; 50 | if (v == parent && child > 1) res!.add(v); 51 | } else if (w != parent) 52 | _low![v] = [(_low![v] as int), (_low![w] as int)].reduce(min); 53 | } 54 | 55 | result() { 56 | return res; 57 | } 58 | } 59 | 60 | void main() async { 61 | File content = File("g.txt"); 62 | List list = await content.readAsLines(); 63 | //读取到文件的顶点数量以及 64 | int v = int.parse(list[0].split(" ")[0]); 65 | int e = int.parse(list[0].split(" ")[1]); 66 | Graph graph = Graph(v, e, list); 67 | FindCutPoints fc = new FindCutPoints(graph); 68 | print("Cut Points in g : " + fc.result().toString()); 69 | 70 | File content2 = File("g2.txt"); 71 | List list2 = await content2.readAsLines(); 72 | //读取到文件的顶点数量以及 73 | int v2 = int.parse(list2[0].split(" ")[0]); 74 | int e2 = int.parse(list2[0].split(" ")[1]); 75 | Graph graph2 = Graph(v2, e2, list2); 76 | FindCutPoints fc2 = new FindCutPoints(graph2); 77 | print("Cut Points in g2 : " + fc2.result().toString()); 78 | 79 | File content3 = File("g3.txt"); 80 | List list3 = await content3.readAsLines(); 81 | //读取到文件的顶点数量以及 82 | int v3 = int.parse(list3[0].split(" ")[0]); 83 | int e3 = int.parse(list3[0].split(" ")[1]); 84 | Graph graph3 = Graph(v3, e3, list3); 85 | FindCutPoints fc3 = new FindCutPoints(graph3); 86 | print("Cut Points in g3 : " + fc3.result().toString()); 87 | 88 | File content5 = File("tree.txt"); 89 | List list5 = await content5.readAsLines(); 90 | //读取到文件的顶点数量以及 91 | int v5 = int.parse(list5[0].split(" ")[0]); 92 | int e5 = int.parse(list5[0].split(" ")[1]); 93 | Graph graph5 = Graph(v5, e5, list5); 94 | FindCutPoints fc4 = new FindCutPoints(graph5); 95 | print("Cut Points in tree : " + fc4.result().toString()); 96 | } 97 | -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/Graph.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图 6 | */ 7 | class Graph{ 8 | int? _V; //图的顶点数量 9 | int? _E; //图的边的数量 10 | List? _treeSet; 11 | 12 | Graph(V, E, List list) { 13 | _V = V; 14 | _E = E; 15 | if (V < 0) throw Exception("V must be non-negative"); 16 | if (E < 0) throw Exception("E must be non-negative"); 17 | _treeSet = List.generate(V, (_) => SplayTreeSet(), growable: false); 18 | 19 | for (int i = 1; i <= E; i++) { 20 | int a = int.parse(list[i].split(" ")[0]); 21 | validateVertex(a); 22 | int b = int.parse(list[i].split(" ")[1]); 23 | validateVertex(b); 24 | (_treeSet![a] as SplayTreeSet).add(b); 25 | (_treeSet![b] as SplayTreeSet).add(a); 26 | } 27 | } 28 | 29 | validateVertex(int v) { 30 | if (v < 0 || v >= _V!) throw new Exception("vertex $v is invalid"); 31 | } 32 | 33 | int? V() { 34 | return _V; 35 | } 36 | 37 | bool hasEdge(int v, int w) { 38 | validateVertex(v); 39 | validateVertex(w); 40 | return (_treeSet![v] as SplayTreeSet).contains(w); 41 | } 42 | 43 | int _degree(int v) { 44 | return _treeSet![v].length; 45 | } 46 | 47 | int? E() { 48 | return _E; 49 | } 50 | 51 | adj(int v) { 52 | validateVertex(v); 53 | return _treeSet![v]; 54 | } 55 | 56 | @override 57 | String toString() { 58 | StringBuffer sb = new StringBuffer(); 59 | sb.write("V = $_V, E = $_E\n"); 60 | for (int j = 0; j < _V!; j++) { 61 | sb.write("节点:$j "); 62 | sb.write("${_treeSet![j].toString()} "); 63 | sb.write('\n'); 64 | } 65 | return sb.toString(); 66 | } 67 | } 68 | void main() async { 69 | File content = File("g.txt"); 70 | List list = await content.readAsLines(); 71 | //读取到文件的顶点数量以及 72 | print(list[0].split(" ")[0]); 73 | print(list[0].split(" ")[1]); 74 | int v = int.parse(list[0].split(" ")[0]) ; 75 | int e = int.parse(list[0].split(" ")[1]) ; 76 | // 77 | Graph adjList= Graph(v, e, list); 78 | print(adjList); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/g.txt: -------------------------------------------------------------------------------- 1 | 7 8 2 | 0 1 3 | 0 2 4 | 1 3 5 | 2 3 6 | 3 5 7 | 4 5 8 | 4 6 9 | 5 6 -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/g2.txt: -------------------------------------------------------------------------------- 1 | 12 16 2 | 0 1 3 | 0 2 4 | 1 3 5 | 2 3 6 | 3 5 7 | 4 5 8 | 4 6 9 | 4 7 10 | 5 6 11 | 6 8 12 | 8 9 13 | 8 10 14 | 8 11 15 | 9 10 16 | 9 11 17 | 10 11 -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/g3.txt: -------------------------------------------------------------------------------- 1 | 4 5 2 | 0 1 3 | 0 2 4 | 1 2 5 | 1 3 6 | 2 3 -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/g4.txt: -------------------------------------------------------------------------------- 1 | 7 8 2 | 0 1 3 | 0 2 4 | 1 3 5 | 1 4 6 | 2 3 7 | 2 6 8 | 3 5 9 | 5 6 -------------------------------------------------------------------------------- /dart/29-Brigde-And-Cut-Points/tree.txt: -------------------------------------------------------------------------------- 1 | 7 6 2 | 0 1 3 | 0 3 4 | 1 6 5 | 2 3 6 | 2 5 7 | 3 4 -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/CC.dart: -------------------------------------------------------------------------------- 1 | import 'Graph.dart'; 2 | import 'dart:io'; 3 | import 'dart:collection'; 4 | import 'WeightedGraph.dart'; 5 | /** 6 | * 图的联通分量BFS 7 | */ 8 | class CC { 9 | WeightedGraph? _G; 10 | 11 | List? _visited; 12 | 13 | int _cccount = 0; 14 | 15 | CC(WeightedGraph G) { 16 | this._G = G; 17 | _visited = List.filled(G.V()!, 0, growable: true); 18 | 19 | for (int i = 0; i < _visited!.length; i++) _visited![i] = -1; 20 | 21 | for (int v = 0; v < G.V()!; v++) { 22 | if (_visited![v] == -1) { 23 | _bfs(v, _cccount); 24 | _cccount++; 25 | } 26 | } 27 | } 28 | 29 | _bfs(int v, int ccid) { 30 | ListQueue queue = ListQueue(); 31 | queue.add(v); 32 | _visited![v] = ccid; 33 | while (!queue.isEmpty) { 34 | int v = queue.removeFirst(); 35 | 36 | for (int w in _G!.adj(v)) { 37 | if (_visited![w] == -1) { 38 | queue.add(w); 39 | _visited![w] = ccid; 40 | } 41 | } 42 | } 43 | } 44 | 45 | int count() { 46 | return _cccount; 47 | } 48 | 49 | bool isConnected(int v, int w) { 50 | _G!.validateVertex(v); 51 | _G!.validateVertex(w); 52 | return _visited![v] == _visited![w]; 53 | } 54 | 55 | components() { 56 | List? res = List.generate(_cccount, (_) => List.generate(0, (_) => 0), 57 | growable: true); 58 | for (int v = 0; v < _G!.V()!; v++) res[_visited![v]].add(v); 59 | return res; 60 | } 61 | } 62 | 63 | void main() async { 64 | File content = File("g.txt"); 65 | List list = await content.readAsLines(); 66 | //读取到文件的顶点数量以及 67 | int v = int.parse(list[0].split(" ")[0]); 68 | int e = int.parse(list[0].split(" ")[1]); 69 | // 70 | WeightedGraph adjList = WeightedGraph(v, e, list); 71 | CC cc = new CC(adjList); 72 | print(cc.count()); 73 | 74 | print(cc.isConnected(0, 6)); 75 | print(cc.isConnected(5, 6)); 76 | 77 | List comp = cc.components(); 78 | for (int ccid = 0; ccid < comp.length; ccid++) { 79 | print("$ccid :: "); 80 | for (int w in comp[ccid]) { 81 | print("$w "); 82 | } 83 | print(""); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/Edge.dart: -------------------------------------------------------------------------------- 1 | class Edge { 2 | int? v, w; 3 | Edge(int v, int w){ 4 | this.v = v; 5 | this.w = w; 6 | } 7 | 8 | @override 9 | String toString(){ 10 | return ("$v-$w"); 11 | } 12 | } -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/Graph.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 图 6 | */ 7 | class Graph{ 8 | int? _V; //图的顶点数量 9 | int? _E; //图的边的数量 10 | List? _treeSet; 11 | 12 | Graph(V, E, List list) { 13 | _V = V; 14 | _E = E; 15 | if (V < 0) throw Exception("V must be non-negative"); 16 | if (E < 0) throw Exception("E must be non-negative"); 17 | _treeSet = List.generate(V, (_) => SplayTreeSet(), growable: false); 18 | 19 | for (int i = 1; i <= E; i++) { 20 | int a = int.parse(list[i].split(" ")[0]); 21 | validateVertex(a); 22 | int b = int.parse(list[i].split(" ")[1]); 23 | validateVertex(b); 24 | (_treeSet![a] as SplayTreeSet).add(b); 25 | (_treeSet![b] as SplayTreeSet).add(a); 26 | } 27 | } 28 | 29 | validateVertex(int v) { 30 | if (v < 0 || v >= _V!) throw new Exception("vertex $v is invalid"); 31 | } 32 | 33 | int? V() { 34 | return _V; 35 | } 36 | 37 | bool hasEdge(int v, int w) { 38 | validateVertex(v); 39 | validateVertex(w); 40 | return (_treeSet![v] as SplayTreeSet).contains(w); 41 | } 42 | 43 | int _degree(int v) { 44 | return _treeSet![v].length; 45 | } 46 | 47 | int? E() { 48 | return _E; 49 | } 50 | 51 | adj(int v) { 52 | validateVertex(v); 53 | return _treeSet![v]; 54 | } 55 | 56 | @override 57 | String toString() { 58 | StringBuffer sb = new StringBuffer(); 59 | sb.write("V = $_V, E = $_E\n"); 60 | for (int j = 0; j < _V!; j++) { 61 | sb.write("节点:$j "); 62 | sb.write("${_treeSet![j].toString()} "); 63 | sb.write('\n'); 64 | } 65 | return sb.toString(); 66 | } 67 | } 68 | void main() async { 69 | File content = File("g.txt"); 70 | List list = await content.readAsLines(); 71 | //读取到文件的顶点数量以及 72 | print(list[0].split(" ")[0]); 73 | print(list[0].split(" ")[1]); 74 | int v = int.parse(list[0].split(" ")[0]) ; 75 | int e = int.parse(list[0].split(" ")[1]) ; 76 | // 77 | Graph adjList= Graph(v, e, list); 78 | print(adjList); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/Kruskal.dart: -------------------------------------------------------------------------------- 1 | import 'WeightedGraph.dart'; 2 | import 'WeightedEdge.dart'; 3 | import 'CC.dart'; 4 | import 'UF.dart'; 5 | import 'dart:io'; 6 | class Kruskal { 7 | WeightedGraph? _G; 8 | 9 | List? mst; 10 | 11 | Kruskal(WeightedGraph G) { 12 | this._G = G; 13 | mst = List.filled(0, WeightedEdge, growable: true); 14 | 15 | CC cc = new CC(G); 16 | if (cc.count() > 1) return; 17 | 18 | List? edges = List.filled(0, WeightedEdge, growable: true); 19 | for (int v = 0; v < _G!.V()!; v++) 20 | for (int w in G.adj(v)) 21 | if (v < w) edges.add(new WeightedEdge(v, w, G.getWeight(v, w))); 22 | 23 | edges.sort(); 24 | 25 | UF uf = new UF(G.V()!); 26 | for (WeightedEdge edge in edges) { 27 | int v = edge.getV(); 28 | int w = edge.getW(); 29 | if (!uf.isConnected(v, w)) { 30 | mst!.add(edge); 31 | uf.unionElements(v, w); 32 | } 33 | } 34 | } 35 | 36 | result() { 37 | return mst; 38 | } 39 | } 40 | 41 | void main() async { 42 | File content = File("g.txt"); 43 | List list = await content.readAsLines(); 44 | //读取到文件的顶点数量以及 45 | int v = int.parse(list[0].split(" ")[0]); 46 | int e = int.parse(list[0].split(" ")[1]); 47 | WeightedGraph g = new WeightedGraph(v,e,list); 48 | Kruskal kruskal = new Kruskal(g); 49 | print(kruskal.result()); 50 | } 51 | -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/Prim.dart: -------------------------------------------------------------------------------- 1 | import 'WeightedGraph.dart'; 2 | import 'WeightedEdge.dart'; 3 | import 'CC.dart'; 4 | import 'dart:collection'; 5 | import 'dart:io'; 6 | 7 | /** 8 | * Prim算法中 9 | * 需要使用到优先级队列 10 | * 而dart中无优先级队列 11 | */ 12 | class Prim { 13 | WeightedGraph? G; 14 | 15 | List? mst; 16 | 17 | Prim(WeightedGraph G) { 18 | this.G = G; 19 | mst = List.filled(0, WeightedEdge, growable: true); 20 | 21 | CC cc = new CC(G); 22 | if (cc.count() > 1) return; 23 | 24 | List? _visited = List.filled(G.V()!, false, growable: true); 25 | _visited[0] = true; 26 | Queue pq = ListQueue(); 27 | 28 | for (int w in G.adj(0)) { 29 | pq.add(new WeightedEdge(0, w, G.getWeight(0, w))); 30 | } 31 | 32 | while (!pq.isEmpty) { 33 | WeightedEdge minEdge = pq.removeFirst(); 34 | if (_visited[minEdge.getV()] && _visited[minEdge.getW()]){ 35 | continue; 36 | } 37 | print("${minEdge.getV()} ${minEdge.getW()} ${minEdge.getWeight()}"); 38 | mst!.add(minEdge); 39 | 40 | int newv = _visited[minEdge.getV()] ? minEdge.getW() : minEdge.getV(); 41 | _visited[newv] = true; 42 | for (int w in G.adj(newv)) 43 | if (!_visited[w]) 44 | pq.add(new WeightedEdge(newv, w, G.getWeight(newv, w))); 45 | } 46 | } 47 | 48 | result() { 49 | return mst; 50 | } 51 | } 52 | 53 | void main() async { 54 | File content = File("g.txt"); 55 | List list = await content.readAsLines(); 56 | //读取到文件的顶点数量以及 57 | int v = int.parse(list[0].split(" ")[0]); 58 | int e = int.parse(list[0].split(" ")[1]); 59 | WeightedGraph g = new WeightedGraph(v, e, list); 60 | Prim prim = new Prim(g); 61 | print(prim.result()); 62 | } 63 | -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/UF.dart: -------------------------------------------------------------------------------- 1 | class UF{ 2 | 3 | List? parent; 4 | 5 | UF(int n){ 6 | parent = List.filled(n,0, growable: true); 7 | for(int i = 0 ; i < n ; i ++) { 8 | parent![i] = i; 9 | } 10 | } 11 | 12 | int find(int p){ 13 | if( p != parent![p] ) 14 | parent![p] = find( parent![p] ); 15 | return parent![p]; 16 | } 17 | 18 | bool isConnected(int p , int q){ 19 | return find(p) == find(q); 20 | } 21 | 22 | unionElements(int p, int q){ 23 | 24 | int pRoot = find(p); 25 | int qRoot = find(q); 26 | 27 | if( pRoot == qRoot ) 28 | return; 29 | 30 | parent![pRoot] = qRoot; 31 | } 32 | } -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/WeightedEdge.dart: -------------------------------------------------------------------------------- 1 | class WeightedEdge implements Comparable { 2 | int _v = 0; 3 | int _w = 0; 4 | int _weight = 0; 5 | 6 | WeightedEdge(this._v, this._w, this._weight); 7 | 8 | @override 9 | int compareTo(other) { 10 | // TODO: implement compareTo 11 | return (_weight - other.getWeight()) as int; 12 | } 13 | 14 | int getV() { 15 | return _v; 16 | } 17 | 18 | int getW() { 19 | return _w; 20 | } 21 | 22 | int getWeight() { 23 | return _weight; 24 | } 25 | 26 | @override 27 | String toString() { 28 | // TODO: implement toString 29 | return ("($_v-$_w: $_weight)"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/WeightedGraph.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:io'; 3 | 4 | /** 5 | * 无向有权图 6 | */ 7 | class WeightedGraph { 8 | int? _V; 9 | 10 | int? _E; 11 | 12 | List? _adj; 13 | 14 | WeightedGraph(V, E, List list) { 15 | this._V = V; 16 | this._E = E; 17 | 18 | _adj = List.generate(_V!, (_) => SplayTreeMap(), growable: false); 19 | 20 | for (int i = 1; i <= E; i++) { 21 | int a = int.parse(list[i].split(" ")[0]); 22 | validateVertex(a); 23 | int b = int.parse(list[i].split(" ")[1]); 24 | validateVertex(b); 25 | int weight = int.parse(list[i].split(" ")[2]); 26 | 27 | if (a == b) throw new Exception("Self Loop is Detected!"); 28 | if (_adj![a].containsKey(b)) { 29 | throw new Exception("Parallel Edges are Detected!"); 30 | } 31 | _adj![a].putIfAbsent(b, () => weight); 32 | _adj![b].putIfAbsent(a, () => weight); 33 | } 34 | } 35 | 36 | validateVertex(int v) { 37 | if (v < 0 || v >= (_V as int)) throw new Exception("vertex $v is invalid"); 38 | } 39 | 40 | int? V() { 41 | return _V; 42 | } 43 | 44 | int? E() { 45 | return _E; 46 | } 47 | 48 | bool hasEdge(int v, int w) { 49 | validateVertex(v); 50 | validateVertex(w); 51 | return _adj![v].containsKey(w); 52 | } 53 | 54 | adj(int v) { 55 | validateVertex(v); 56 | return (_adj![v] as SplayTreeMap).keys; 57 | } 58 | 59 | int getWeight(int v, int w) { 60 | if (hasEdge(v, w)) return _adj![v][w]; 61 | throw new Exception("No edge $v-$w"); 62 | } 63 | 64 | int degree(int v) { 65 | validateVertex(v); 66 | return _adj![v].size(); 67 | } 68 | 69 | removeEdge(int v, int w) { 70 | validateVertex(v); 71 | validateVertex(w); 72 | if (_adj![v].containsKey(w)) { 73 | _E = _E! - 1; 74 | } 75 | ; 76 | _adj![v].remove(w); 77 | _adj![w].remove(v); 78 | } 79 | @override 80 | String toString(){ 81 | StringBuffer sb = new StringBuffer(); 82 | 83 | sb.write("V = $_V, E = $E\n"); 84 | for(int v = 0; v < (_V as int); v ++){ 85 | sb.write("$v : "); 86 | (_adj![v] as SplayTreeMap).entries.forEach((element) { sb.write("( ${element.key}:${element.value} )");}); 87 | sb.write('\n'); 88 | } 89 | return sb.toString(); 90 | } 91 | } 92 | 93 | void main() async { 94 | File content = File("g.txt"); 95 | List list = await content.readAsLines(); 96 | //读取到文件的顶点数量以及 97 | int v = int.parse(list[0].split(" ")[0]); 98 | int e = int.parse(list[0].split(" ")[1]); 99 | WeightedGraph g = new WeightedGraph(v, e, list); 100 | print(g); 101 | } 102 | -------------------------------------------------------------------------------- /dart/30-Minimum-Tree-Spanning/g.txt: -------------------------------------------------------------------------------- 1 | 7 12 2 | 0 1 2 3 | 0 3 7 4 | 0 5 2 5 | 1 2 1 6 | 1 3 4 7 | 1 4 3 8 | 1 5 5 9 | 2 4 4 10 | 2 5 4 11 | 3 4 1 12 | 3 6 5 13 | 4 6 7 -------------------------------------------------------------------------------- /dart/Dart-Basic.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /python/__pycache__/sort.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewPracticer/Python-Flutter-Dart-DataStructure/72474cf32e78b68f4301af6ac92e8cf1c8a84168/python/__pycache__/sort.cpython-37.pyc -------------------------------------------------------------------------------- /python/linkedlist.py: -------------------------------------------------------------------------------- 1 | class Node(object): 2 | 3 | def __init__(self,value): 4 | self.value = value; 5 | self.next = None; 6 | 7 | def __str__(self): 8 | return self.value; 9 | 10 | ''' 11 | 链表 12 | ''' 13 | class LinkedList(object): 14 | 15 | def __init__(self): 16 | self.head = None 17 | self.size = 0 18 | 19 | def getSize(self): 20 | return self.size 21 | 22 | def isEmpty(self): 23 | return self.size == 0; 24 | 25 | #头部添加元素 26 | def add(self, value): 27 | node = Node(value) 28 | node.next = self.head 29 | self.head = node 30 | self.size +=1 31 | 32 | # 尾部添加元素 33 | def append(self, value): 34 | node = Node(value) 35 | if self.isEmpty(): 36 | self.head = node 37 | else: 38 | cur = self.head 39 | while cur.next != None: 40 | cur = cur.next 41 | cur.next = node 42 | self.size +=1 43 | 44 | # 指定位置添加元素 45 | def insert(self, pos, value): 46 | if pos <= 0: 47 | self.add(value) 48 | elif pos > self.size: 49 | self.append(value) 50 | else: 51 | node = Node(value) 52 | count = 0 53 | pre = self.head 54 | while count < (pos-1): 55 | count += 1 56 | pre = pre.next 57 | node.next = pre.next 58 | pre.next = node 59 | self.size +=1 60 | 61 | # 删除节点 62 | def remove(self,value): 63 | cur = self.head 64 | pre = None 65 | isFind = False 66 | while cur != None: 67 | if cur.value == value: 68 | if not pre: 69 | self.head = cur.next 70 | else: 71 | pre.next = cur.next 72 | self.size -=1 73 | isFind = True 74 | break 75 | else: 76 | pre = cur 77 | cur = cur.next 78 | return isFind 79 | 80 | # 查找节点是否存在 81 | def search(self,value): 82 | cur = self.head 83 | while cur != None: 84 | if cur.value == value: 85 | return True 86 | cur = cur.next 87 | return False 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /python/loopqueue.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 循环队列 3 | ''' 4 | class LoopQueue(object): 5 | 6 | def __init__(self, n=10): 7 | self.arr = [None] * (n) 8 | self.front = 0 9 | self.tail = 0 10 | self.size = 0 11 | 12 | def getCapacity(self): 13 | capacity = len(self.arr) - 1; 14 | return capacity; 15 | 16 | def dequeue(self): 17 | if self.isEmpty() : 18 | raise Exception("Cannot dequeue from an empty queue") 19 | ret = self.arr[self.front] 20 | self.arr[self.front] = None 21 | self.front = (self.front + 1)%len(self.arr) 22 | self.size -=1 23 | if((self.size == self.getCapacity()//4)) and (self.getCapacity()/2 !=0): 24 | resize(self.getCapacity()//2) 25 | return ret 26 | 27 | def resize(self,newCapacity): 28 | newArr = [None]*(newCapacity+1) 29 | for i in range(0,len(self.arr)): 30 | newArr[i] = self.arr[(i+self.front)%len(self.arr)]; 31 | self.arr = newArr 32 | self.front = 0; 33 | self.tail = self.size; 34 | 35 | def enqueue(self,element): 36 | print('当前大小:',self.size) 37 | if ((self.tail+1)%len(self.arr)) == self.front: 38 | self.resize(self.getCapacity()*2) 39 | self.arr[self.tail] = element 40 | self.tail = (self.tail +1)% len(self.arr) 41 | self.size += 1 42 | print('当前大小:',self.size) 43 | 44 | def getFront(self): 45 | if(self.isEmpty()): 46 | raise Exception("Queue is empty.") 47 | return self.arr[self.front] 48 | 49 | def getSize(self): 50 | return len(self.arr) 51 | 52 | def isEmpty(self): 53 | return self.front == self.tail 54 | 55 | def __str__(self): 56 | return "front ["+" ".join(map(str, self.arr)) + "] tail" 57 | 58 | if __name__ == '__main__': 59 | loopQueue = LoopQueue(); 60 | for i in range(0,30): 61 | loopQueue.enqueue(i); 62 | print(loopQueue) 63 | 64 | 65 | -------------------------------------------------------------------------------- /python/queue.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 队列 3 | ''' 4 | class Queue(object): 5 | 6 | # 初始化 7 | def __init__(self): 8 | self.__list = [] 9 | 10 | #添加元素 11 | def push(self,element): 12 | self.__list.append(element) 13 | 14 | # 弹出元素 15 | def pop(self): 16 | if self.isEmpty(): 17 | return None 18 | else: 19 | return self.__list.pop(0) 20 | 21 | #是否为空 22 | def isEmpty(self): 23 | return len(self.__list) == 0 24 | 25 | def getSize(self): 26 | return len(self.__list) 27 | 28 | def __str__(self): 29 | return " ".join(map(str, self.__list)) 30 | 31 | if __name__ == '__main__': 32 | testQueue = Queue(); 33 | testQueue.push(1) 34 | testQueue.push(2) 35 | testQueue.push(3) 36 | testQueue.push(4) 37 | print(testQueue) 38 | testQueue.pop() 39 | print(testQueue) 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /python/stack.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 栈 3 | ''' 4 | class Stack(object): 5 | 6 | # 初始化 7 | def __init__(self): 8 | self.__list = [] 9 | 10 | #添加元素 11 | def push(self,element): 12 | self.__list.append(element) 13 | 14 | # 弹出元素 15 | def pop(self): 16 | if self.isEmpty(): 17 | return None 18 | else: 19 | return self.__list.pop() 20 | 21 | #是否为空 22 | def isEmpty(self): 23 | return len(self.__list) == 0 24 | 25 | def getSize(self): 26 | return len(self.__list) 27 | 28 | def __str__(self): 29 | return " ".join(map(str, self.__list)) 30 | 31 | if __name__ == '__main__': 32 | testStack = Stack(); 33 | testStack.push(1) 34 | testStack.push(2) 35 | testStack.push(3) 36 | testStack.push(4) 37 | print(testStack) 38 | testStack.pop() 39 | print(testStack) 40 | 41 | 42 | 43 | 44 | 45 | --------------------------------------------------------------------------------