├── .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 |
--------------------------------------------------------------------------------