Skip to content

Commit 8a5d8c1

Browse files
committed
Upgrade to NNBD sort algorithms
1 parent 1be031c commit 8a5d8c1

File tree

8 files changed

+130
-145
lines changed

8 files changed

+130
-145
lines changed

lib/sorts/common.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// @dart=2.9
1+
import '../heaps/base.dart';
2+
23
/// Comparator function compared [left] with [right]
34
typedef Comparator<T extends Comparable> = bool Function(T left, T right);
45

@@ -54,7 +55,7 @@ bool isReverseSorted<T extends Comparable>(List<T> list,
5455
/// The minimum and maximum values are stored as "min"
5556
/// and "max" kets in the [Map] returned.
5657
Map<String, num> findMinMax(List<num> list) {
57-
if (list.isEmpty) return null;
58+
if (list.isEmpty) throw InvalidIndexError();
5859

5960
var min = list[0];
6061
var max = list[0];

lib/sorts/distribution.dart

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// @dart=2.9
21
import 'common.dart';
32
import 'insertion.dart';
43

@@ -29,8 +28,9 @@ List<int> _countingSort(List<int> list) {
2928
if (list.isEmpty) return list;
3029

3130
var boundaries = findMinMax(list);
32-
var bucket = List<int>.filled(boundaries['max'] + 1, 0);
33-
var sorted = List<int>(list.length);
31+
var max = boundaries['max'] as int;
32+
var bucket = List<int>.filled(max + 1, 0);
33+
var sorted = List<int>.filled(list.length, 0);
3434

3535
for (var item in list) {
3636
bucket[item]++;
@@ -56,7 +56,7 @@ List<int> countingSort(List<int> list, {bool desc = false}) {
5656

5757
void _inPlaceCountSort(List<int> list, int exp) {
5858
var n = list.length;
59-
var sorted = List<int>(n);
59+
var sorted = List<int>.filled(n, 0);
6060
var count = List<int>.filled(10, 0);
6161

6262
for (var i = 0; i < n; i++) {
@@ -81,8 +81,9 @@ List<int> _radixSort(List<int> list) {
8181
if (list.isEmpty) return list;
8282

8383
var boundaries = findMinMax(list);
84+
var max = boundaries['max'] as int;
8485

85-
for (var exp = 1; boundaries['max'] ~/ exp > 0; exp *= 10) {
86+
for (var exp = 1; max ~/ exp > 0; exp *= 10) {
8687
_inPlaceCountSort(list, exp);
8788
}
8889

@@ -100,11 +101,12 @@ List<int> pigeonholeSort(List<int> list, {bool desc = false}) {
100101
if (list.isEmpty) return list;
101102

102103
var boundaries = findMinMax(list);
103-
var min = boundaries['min'];
104-
var size = (boundaries['max'] - boundaries['min']) + 1;
104+
var max = boundaries['max'] as int;
105+
var min = boundaries['min'] as int;
106+
var size = (max - min) + 1;
105107

106108
var pigeonHole = List<int>.filled(size, 0);
107-
var sorted = List<int>(list.length);
109+
var sorted = List<int>.filled(list.length, 0);
108110

109111
for (var item in list) {
110112
pigeonHole[item - min]++;
@@ -127,14 +129,16 @@ List<T> bucketSort<T extends num>(List<T> list, {bool desc = false}) {
127129
if (list.isEmpty) return list;
128130

129131
var boundaries = findMinMax(list);
132+
var max = boundaries['max'] as num;
133+
var min = boundaries['min'] as num;
130134

131-
if (boundaries['min'] < 0) {
135+
if (min < 0) {
132136
throw FormatException('This version only takes positive numbers');
133137
}
134138

135139
var inputLength = list.length;
136-
var bucketSize = (boundaries['max'] * inputLength).ceil() + 1;
137-
var buckets = List<List<T>>(bucketSize);
140+
var bucketSize = (max * inputLength).ceil() + 1;
141+
var buckets = List<List<T>>.filled(bucketSize, []);
138142
for (var i = 0; i < buckets.length; i++) {
139143
buckets[i] = <T>[];
140144
}
@@ -144,6 +148,7 @@ List<T> bucketSort<T extends num>(List<T> list, {bool desc = false}) {
144148
buckets[idx].add(list[i]);
145149
}
146150

147-
var sorted = buckets.fold(<T>[], (acc, el) => acc + insertionSort(el));
151+
var sorted = buckets.fold(<T>[],
152+
(List<T> acc, el) => acc + insertionSort(el));
148153
return desc ? sorted.reversed.toList() : sorted;
149154
}

test/sorts/common_test.dart

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
1-
// @dart=2.9
1+
import 'package:algorithms/heaps/base.dart';
22
import 'package:test/test.dart';
33

44
import 'package:algorithms/sorts/common.dart';
55

66
void main() {
7-
List<num> anyList, singleValuedList, emptyList;
7+
List<num>? anyList, singleValuedList, emptyList;
88
setUp(() {
99
emptyList = [];
1010
singleValuedList = [42];
1111
anyList = [32, 23, -161, 43, 65, -2, 45, 233, -12];
1212
});
1313

1414
test('Is unsorted', () {
15-
expect(isSorted(anyList), equals(false));
15+
expect(isSorted(anyList!), equals(false));
1616
});
1717

1818
test('Is sorted', () {
19-
anyList.sort();
20-
expect(isSorted(anyList), equals(true));
21-
expect(isSorted(emptyList), equals(true));
22-
expect(isSorted(singleValuedList), equals(true));
19+
anyList!.sort();
20+
expect(isSorted(anyList!), equals(true));
21+
expect(isSorted(emptyList!), equals(true));
22+
expect(isSorted(singleValuedList!), equals(true));
2323
});
2424

2525
test('Is reverse sorted', () {
26-
anyList.sort();
27-
expect(isReverseSorted(anyList.reversed.toList()), equals(true));
28-
expect(isReverseSorted(emptyList), equals(true));
29-
expect(isReverseSorted(singleValuedList), equals(true));
26+
anyList!.sort();
27+
expect(isReverseSorted(anyList!.reversed.toList()), equals(true));
28+
expect(isReverseSorted(emptyList!), equals(true));
29+
expect(isReverseSorted(singleValuedList!), equals(true));
3030
});
3131

3232
test('Find min and max', () {
33-
expect(findMinMax(anyList), equals({'min': -161, 'max': 233}));
34-
expect(findMinMax(emptyList), equals(null));
35-
expect(findMinMax(singleValuedList), equals({'min': 42, 'max': 42}));
33+
expect(findMinMax(anyList!), equals({'min': -161, 'max': 233}));
34+
expect(() => findMinMax(emptyList!), throwsA(isA<InvalidIndexError>()));
35+
expect(findMinMax(singleValuedList!), equals({'min': 42, 'max': 42}));
3636
});
3737
}

test/sorts/distribution_test.dart

Lines changed: 38 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
// @dart=2.9
21
import 'package:test/test.dart';
32

43
import 'package:algorithms/sorts/distribution.dart';
54

65
void main() {
7-
List<int> randomList;
8-
List<int> positiveRandomList;
9-
List<int> sortedRandomListAscending;
10-
List<int> sortedRandomListDescending;
11-
List<int> sortedPositiveRandomListAscending;
12-
List<int> sortedPositiveRandomListDescending;
13-
List<int> allNegatives;
14-
List<int> someNegatives;
15-
List<int> sortedAllNegatives;
16-
List<int> sortedSomeNegatives;
17-
List<num> randomDistribution;
18-
List<num> randomDistributionSorted;
19-
20-
List<int> emptyList;
21-
6+
List<int>? randomList, positiveRandomList, sortedRandomListAscending,
7+
sortedRandomListDescending, sortedPositiveRandomListAscending,
8+
sortedPositiveRandomListDescending, allNegatives, someNegatives,
9+
sortedAllNegatives, sortedSomeNegatives, emptyList;
10+
List<double>? randomDistribution, randomDistributionSorted;
2211
setUp(() {
2312
emptyList = [];
2413
randomList = [2, 4, 2, 1, -1, 0, 20];
@@ -39,67 +28,67 @@ void main() {
3928
});
4029

4130
test('Pigeonhole Sort', () {
42-
expect(pigeonholeSort(randomList), equals(sortedRandomListAscending));
43-
expect(pigeonholeSort(randomList, desc: false),
31+
expect(pigeonholeSort(randomList!), equals(sortedRandomListAscending));
32+
expect(pigeonholeSort(randomList!, desc: false),
4433
equals(sortedRandomListAscending));
45-
expect(pigeonholeSort(randomList, desc: true),
34+
expect(pigeonholeSort(randomList!, desc: true),
4635
equals(sortedRandomListDescending));
4736

48-
expect(pigeonholeSort(emptyList), equals(emptyList));
49-
expect(pigeonholeSort(emptyList, desc: false), equals(emptyList));
50-
expect(pigeonholeSort(emptyList, desc: true), equals(emptyList));
37+
expect(pigeonholeSort(emptyList!), equals(emptyList));
38+
expect(pigeonholeSort(emptyList!, desc: false), equals(emptyList));
39+
expect(pigeonholeSort(emptyList!, desc: true), equals(emptyList));
5140
});
5241

5342
test('Counting Sort', () {
54-
expect(countingSort(positiveRandomList),
43+
expect(countingSort(positiveRandomList!),
5544
equals(sortedPositiveRandomListAscending));
56-
expect(countingSort(positiveRandomList, desc: false),
45+
expect(countingSort(positiveRandomList!, desc: false),
5746
equals(sortedPositiveRandomListAscending));
58-
expect(countingSort(positiveRandomList, desc: true),
47+
expect(countingSort(positiveRandomList!, desc: true),
5948
equals(sortedPositiveRandomListDescending));
6049

61-
expect(countingSort(emptyList), equals(emptyList));
62-
expect(countingSort(emptyList, desc: false), equals(emptyList));
63-
expect(countingSort(emptyList, desc: true), equals(emptyList));
50+
expect(countingSort(emptyList!), equals(emptyList));
51+
expect(countingSort(emptyList!, desc: false), equals(emptyList));
52+
expect(countingSort(emptyList!, desc: true), equals(emptyList));
6453

65-
expect(countingSort(allNegatives), equals(sortedAllNegatives));
66-
expect(countingSort(someNegatives), equals(sortedSomeNegatives));
54+
expect(countingSort(allNegatives!), equals(sortedAllNegatives));
55+
expect(countingSort(someNegatives!), equals(sortedSomeNegatives));
6756
});
6857

6958
test('Radix Sort for positive numbers', () {
70-
expect(radixSort(positiveRandomList),
59+
expect(radixSort(positiveRandomList!),
7160
equals(sortedPositiveRandomListAscending));
72-
expect(radixSort(positiveRandomList, desc: false),
61+
expect(radixSort(positiveRandomList!, desc: false),
7362
equals(sortedPositiveRandomListAscending));
74-
expect(radixSort(positiveRandomList, desc: true),
63+
expect(radixSort(positiveRandomList!, desc: true),
7564
equals(sortedPositiveRandomListDescending));
7665

77-
expect(radixSort(emptyList), equals(emptyList));
78-
expect(radixSort(emptyList, desc: false), equals(emptyList));
79-
expect(radixSort(emptyList, desc: true), equals(emptyList));
66+
expect(radixSort(emptyList!), equals(emptyList));
67+
expect(radixSort(emptyList!, desc: false), equals(emptyList));
68+
expect(radixSort(emptyList!, desc: true), equals(emptyList));
8069

81-
expect(radixSort(allNegatives), equals(sortedAllNegatives));
82-
expect(radixSort(someNegatives), equals(sortedSomeNegatives));
70+
expect(radixSort(allNegatives!), equals(sortedAllNegatives));
71+
expect(radixSort(someNegatives!), equals(sortedSomeNegatives));
8372
});
8473

8574
test('Bucket sort for positive numbers', () {
86-
expect(bucketSort(positiveRandomList),
75+
expect(bucketSort(positiveRandomList!),
8776
equals(sortedPositiveRandomListAscending));
88-
expect(bucketSort(positiveRandomList, desc: false),
77+
expect(bucketSort(positiveRandomList!, desc: false),
8978
equals(sortedPositiveRandomListAscending));
90-
expect(bucketSort(positiveRandomList, desc: true),
79+
expect(bucketSort(positiveRandomList!, desc: true),
9180
equals(sortedPositiveRandomListDescending));
92-
expect(bucketSort(randomDistribution), equals(randomDistributionSorted));
93-
expect(bucketSort(randomDistribution, desc: true),
94-
equals(randomDistributionSorted.reversed));
81+
expect(bucketSort(randomDistribution!), equals(randomDistributionSorted));
82+
expect(bucketSort(randomDistribution!, desc: true),
83+
equals(randomDistributionSorted!.reversed));
9584

96-
expect(bucketSort(emptyList), equals(emptyList));
97-
expect(bucketSort(emptyList, desc: false), equals(emptyList));
98-
expect(bucketSort(emptyList, desc: true), equals(emptyList));
85+
expect(bucketSort(emptyList!), equals(emptyList));
86+
expect(bucketSort(emptyList!, desc: false), equals(emptyList));
87+
expect(bucketSort(emptyList!, desc: true), equals(emptyList));
9988
});
10089

10190
test('Bucket sort for negative numbers', () {
102-
expect(() => bucketSort(allNegatives), throwsA(isA<FormatException>()));
103-
expect(() => bucketSort(someNegatives), throwsA(isA<FormatException>()));
91+
expect(() => bucketSort(allNegatives!), throwsA(isA<FormatException>()));
92+
expect(() => bucketSort(someNegatives!), throwsA(isA<FormatException>()));
10493
});
10594
}

test/sorts/exchange_test.dart

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
// @dart=2.9
21
import 'package:test/test.dart';
32

43
import 'package:algorithms/sorts/exchange.dart';
54

65
void main() {
7-
List<int> randomList;
8-
List<int> sortedRandomListAscending;
9-
List<int> sortedRandomListDescending;
6+
List<int>? randomList, sortedRandomListAscending, sortedRandomListDescending;
107

11-
List<String> emptyList;
8+
List<String>? emptyList;
129

1310
bool ascendingFn(left, right) => left <= right;
1411
bool descendingFn(left, right) => left >= right;
@@ -21,50 +18,50 @@ void main() {
2118
});
2219

2320
test('Bubble Sort', () {
24-
expect(bubbleSort(randomList), equals(sortedRandomListAscending));
21+
expect(bubbleSort(randomList!), equals(sortedRandomListAscending));
2522
expect(
26-
bubbleSort(randomList, ascendingFn), equals(sortedRandomListAscending));
27-
expect(bubbleSort(randomList, descendingFn),
23+
bubbleSort(randomList!, ascendingFn), equals(sortedRandomListAscending));
24+
expect(bubbleSort(randomList!, descendingFn),
2825
equals(sortedRandomListDescending));
2926

30-
expect(bubbleSort(emptyList), equals(emptyList));
31-
expect(bubbleSort(emptyList, ascendingFn), equals(emptyList));
32-
expect(bubbleSort(emptyList, descendingFn), equals(emptyList));
27+
expect(bubbleSort(emptyList!), equals(emptyList));
28+
expect(bubbleSort(emptyList!, ascendingFn), equals(emptyList));
29+
expect(bubbleSort(emptyList!, descendingFn), equals(emptyList));
3330
});
3431

3532
test('Odd-Event Sort', () {
36-
expect(oddEvenSort(randomList), equals(sortedRandomListAscending));
37-
expect(oddEvenSort(randomList, ascendingFn),
33+
expect(oddEvenSort(randomList!), equals(sortedRandomListAscending));
34+
expect(oddEvenSort(randomList!, ascendingFn),
3835
equals(sortedRandomListAscending));
39-
expect(oddEvenSort(randomList, descendingFn),
36+
expect(oddEvenSort(randomList!, descendingFn),
4037
equals(sortedRandomListDescending));
4138

42-
expect(oddEvenSort(emptyList), equals(emptyList));
43-
expect(oddEvenSort(emptyList, ascendingFn), equals(emptyList));
44-
expect(oddEvenSort(emptyList, descendingFn), equals(emptyList));
39+
expect(oddEvenSort(emptyList!), equals(emptyList));
40+
expect(oddEvenSort(emptyList!, ascendingFn), equals(emptyList));
41+
expect(oddEvenSort(emptyList!, descendingFn), equals(emptyList));
4542
});
4643

4744
test('Gnome Sort', () {
48-
expect(gnomeSort(randomList), equals(sortedRandomListAscending));
45+
expect(gnomeSort(randomList!), equals(sortedRandomListAscending));
4946
expect(
50-
gnomeSort(randomList, ascendingFn), equals(sortedRandomListAscending));
51-
expect(gnomeSort(randomList, descendingFn),
47+
gnomeSort(randomList!, ascendingFn), equals(sortedRandomListAscending));
48+
expect(gnomeSort(randomList!, descendingFn),
5249
equals(sortedRandomListDescending));
5350

54-
expect(gnomeSort(emptyList), equals(emptyList));
55-
expect(gnomeSort(emptyList, ascendingFn), equals(emptyList));
56-
expect(gnomeSort(emptyList, descendingFn), equals(emptyList));
51+
expect(gnomeSort(emptyList!), equals(emptyList));
52+
expect(gnomeSort(emptyList!, ascendingFn), equals(emptyList));
53+
expect(gnomeSort(emptyList!, descendingFn), equals(emptyList));
5754
});
5855

5956
test('Quick Sort', () {
60-
expect(quickSort(randomList), equals(sortedRandomListAscending));
57+
expect(quickSort(randomList!), equals(sortedRandomListAscending));
6158
expect(
62-
quickSort(randomList, ascendingFn), equals(sortedRandomListAscending));
63-
expect(quickSort(randomList, descendingFn),
59+
quickSort(randomList!, ascendingFn), equals(sortedRandomListAscending));
60+
expect(quickSort(randomList!, descendingFn),
6461
equals(sortedRandomListDescending));
6562

66-
expect(quickSort(emptyList), equals(emptyList));
67-
expect(quickSort(emptyList, ascendingFn), equals(emptyList));
68-
expect(quickSort(emptyList, descendingFn), equals(emptyList));
63+
expect(quickSort(emptyList!), equals(emptyList));
64+
expect(quickSort(emptyList!, ascendingFn), equals(emptyList));
65+
expect(quickSort(emptyList!, descendingFn), equals(emptyList));
6966
});
7067
}

0 commit comments

Comments
 (0)