Skip to content

Commit

Permalink
LSD排序,MSD排序,桶排序
Browse files Browse the repository at this point in the history
  • Loading branch information
tianqing.liang committed Sep 10, 2021
1 parent d95f037 commit 7acb29b
Show file tree
Hide file tree
Showing 11 changed files with 587 additions and 4 deletions.
21 changes: 21 additions & 0 deletions 22-CountingSort-And-RadixSort/ArrayGenerator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'dart:math';

class ArrayGenerator{

static List generateOrderedArray(int n){
List arr = List.filled(n, true);
for(int i = 0;i<n;i++){
arr[i] =i;
}
return arr;
}

static List generateRandomArray(int n,int bound){
List arr = List.filled(n, true);
Random random = new Random();
for(int i = 0; i < n; i ++){
arr[i] = random.nextInt(bound);
}
return arr;
}
}
44 changes: 44 additions & 0 deletions 22-CountingSort-And-RadixSort/LSDSort.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class LSDSort {
LSDSort() {}

static sort(List? arr, int W) {
for (String s in arr!)
if (s.length != W) {
throw new Exception("All Strings' length must be the same.");
}
int R = 256;

List temp = List.filled(arr.length, String, growable: true);
List index = List.filled(R + 1, 0, growable: true);
for (int r = W - 1; r >= 0; r--) {
// O(n)
List cnt = List.filled(R, 0, growable: true);
for (String s in arr) {
cnt[s[r].codeUnits[0]]++;
}
// O(R)
for (int i = 0; i < R; i++) {
index[i + 1] = index[i] + cnt[i];
}
// O(n)
for (String s in arr) {
temp[index[s[r].codeUnits[0]]] = s;
index[s[r].codeUnits[0]]++;
}
// O(n)
for (int i = 0; i < arr.length; i++) arr[i] = temp[i];
}
}


}

void main() {
List arr = ["BCA", "CAB", "ACB", "BAC", "ABC", "CBA"];
LSDSort.sort(arr, 3);
for (String s in arr) {
print(s);
}
}


68 changes: 68 additions & 0 deletions 22-CountingSort-And-RadixSort/ShellSort.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import 'SortingHelper.dart';
import 'ArrayGenerator.dart';

/**
* 希尔排序
*/
class ShellSort {
//初始版本
static sort(List? data) {
int h = (data!.length / 2).toInt();
while (h >= 1) {
for (int start = 0; start < h; start++) {
// 对 data[start, start + h, start + 2h, start + 3h ...], 进行插入排序
for (int i = start + h; i < data.length; i += h) {
var t = data[i];
int j;
for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h)
data[j] = data[j - h];
data[j] = t;
}
}
h = (h / 2).toInt();
}
}

//希尔排序优化
static sort2(List? data) {
int h = (data!.length / 2).toInt();
while (h >= 1) {
for (int i = h; i < data.length; i++) {
var t = data[i];
int j;
for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) {
data[j] = data[j - h];
}
data[j] = t;
}
h = (h / 2).toInt();
}
}

//希尔排序设定步长序列
static sort3(List? data) {
int h = 1;
while (h < data!.length) {
h = 3 * h + 1;
}
// 1, 4, 13, 40 ...
while (h >= 1) {
for (int i = h; i < data.length; i++) {
var t = data[i];
int j;
for (j = i; j - h >= 0 && t.compareTo(data[j - h]) < 0; j -= h) {
data[j] = data[j - h];
}
data[j] = t;
}
h = (h / 3).toInt();
}
}
}

void main() {
int n = 100000;
List arr = ArrayGenerator.generateRandomArray(n, n);

SortingHelper.sortTest("ShellSort", arr);
}
46 changes: 46 additions & 0 deletions 22-CountingSort-And-RadixSort/SortingHelper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'ShellSort.dart';

class SortingHelper {
SortingHelper() {}

static bool isSorted(List? arr) {
for (int i = 1; i < arr!.length; i++)
if (arr[i - 1].compareTo(arr[i]) > 0) return false;
return true;
}

static sortTest(String sortname, List? arr) {
var now = new DateTime.now();
num startTime = now.millisecondsSinceEpoch;

if (sortname == "SelectionSort") {
// SelectionSort.sort(arr);
} else if (sortname == "InsertionSort") {
// InsertionSort.sort(arr);
} else if (sortname == "MergeSort") {
// MergeSort.sort(arr);
} else if (sortname == "MergeSortBU") {
// MergeSort.sortBU(arr);
} else if (sortname == "QuickSort") {
// QuickSort.sort(arr);
} else if (sortname == "QuickSort2Ways") {
// QuickSort.sort2ways(arr);
} else if (sortname == "QuickSort3Ways") {
// QuickSort.sort3ways(arr);
} else if (sortname == "QuickSort3Ways") {
// QuickSort.sort3ways(arr);
} else if (sortname == "HeapSort") {
// HeapSort.sort(arr);
} else if (sortname == "BubbleSort") {
// BubbleSort.sort(arr);
} else if (sortname == "ShellSort") {
ShellSort.sort(arr);
}
var endNow = new DateTime.now();
num endTime = endNow.millisecondsSinceEpoch;
print("开始时间:$startTime : 结束时间:$endTime");
double time = (endTime - startTime) / 1000.0;
if (!SortingHelper.isSorted(arr)) throw new Exception(sortname + " failed");
print("$sortname , n = ${arr!.length}: $time s");
}
}
21 changes: 21 additions & 0 deletions 23-MSDSort-And-BucketSort/ArrayGenerator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'dart:math';

class ArrayGenerator{

static List generateOrderedArray(int n){
List arr = List.filled(n, true);
for(int i = 0;i<n;i++){
arr[i] =i;
}
return arr;
}

static List generateRandomArray(int n,int bound){
List arr = List.filled(n, true);
Random random = new Random();
for(int i = 0; i < n; i ++){
arr[i] = random.nextInt(bound);
}
return arr;
}
}
93 changes: 93 additions & 0 deletions 23-MSDSort-And-BucketSort/BucketSort.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import 'ArrayGenerator.dart';
import 'SortingHelper.dart';
import 'dart:math';

class BucketSort {
BucketSort() {}

static sort(List<int> arr, int B) {
if (B <= 1) throw new Exception("B must be > 1");

List temp = List.filled(arr.length, 0, growable: true);
_sortDetail(arr, 0, arr.length - 1, B, temp);
}

static _sortDetail(List<int> arr, int left, int right, int B, List? temp) {
if (left >= right) return;

int maxv = 1 >> 32, minv = 1 << 32;
for (int i = left; i <= right; i++) {
maxv = [maxv, arr[i]].reduce(max);
minv = [minv, arr[i]].reduce(min);
}

if (maxv == minv) {return;}

int d =
((maxv - minv + 1) / B).toInt() + ((maxv - minv + 1) % B > 0 ? 1 : 0);

List cnt = List.filled(B, 0, growable: true);
List index = List.filled(B + 1, 0, growable: true);

// O(n)
for (int i = left; i <= right; i++) cnt[((arr[i] - minv) / d).toInt()]++;

// O(R)
for (int i = 0; i < B; i++) {
index[i + 1] = index[i] + cnt[i];
}
// O(n)
for (int i = left; i <= right; i++) {
int p = ((arr[i] - minv) / d).toInt();
temp![(left + index[p]).toInt()] = arr[i];
index[p]++;
}

// O(n)
for (int i = left; i <= right; i++) {
arr[i] = temp![i];
}

// 递归下去:
_sortDetail(arr, left, (left + index[0] - 1).toInt(), B, temp);
for (int i = 0; i < B - 1; i++)
_sortDetail(arr, (left + index[i]).toInt(),
(left + index[i + 1] - 1).toInt(), B, temp);
}

static sort2(List<int> arr, int c) {
if (c <= 0) throw new Exception("c must be > 0");

int maxv = 1 >> 32, minv = 1 << 32;
for (int e in arr) {
maxv = [maxv, e].reduce(max);
minv = [minv, e].reduce(min);
}

int range = maxv - minv + 1; // arr 中的数据范围
int B = (range / c).toInt() + (range % c > 0 ? 1 : 0); // 根据数据范围决定桶的个数

List buckets = List.filled(B, List, growable: true);
// for(int i = 0; i < B; i ++)
// buckets[i] = new LinkedList<>();
for (int e in arr) {
buckets[((e - minv) / range).toInt()].add(e);
}
for (int i = 0; i < B; i++) {
buckets[i].sort();
}
int index = 0;
for (int i = 0; i < B; i++) for (int e in buckets[i]) {
arr[index++] = e;
}
}
}

void main() {
int n = 1000000;
List? arr = ArrayGenerator.generateRandomArray(n, n);
List? arr2 = List.from(arr);

//SortingHelper.sortTest("BucketSort", arr);
//SortingHelper.sortTest("BucketSort2", arr2);
}
50 changes: 50 additions & 0 deletions 23-MSDSort-And-BucketSort/MSDSort.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class MSDSort {
MSDSort() {}

static sort(List? arr) {
int N = arr!.length;
List? temp = List.filled(N, String, growable: true);
_sortDetail(arr, 0, N - 1, 0, temp);
}

static _sortDetail(List? arr, int left, int right, int r, List? temp) {
if (left >= right) return;

int R = 256;
List? cnt = List.filled(R + 1, 0, growable: true);
List? index = List.filled(R + 2, 0, growable: true);

// O(n)
for (int i = left; i <= right; i++) {
cnt[r >= arr![i].length ? 0 : (arr[i][r].codeUnits[0] + 1)]++;
}
// O(R)
for (int i = 0; i < R + 1; i++) {
index[i + 1] = index[i] + cnt[i];
}
// O(n)
for (int i = left; i <= right; i++) {
temp![index[r >= arr![i].length ? 0 : (arr[i][r].codeUnits[0] + 1)] +
left] = arr[i];
index[r >= arr[i].length ? 0 : (arr[i][r].codeUnits[0] + 1)]++;
}

// O(n)
for (int i = left; i <= right; i++) {
arr![i] = temp![i];
}

for (int i = 0; i < R; i++) {
_sortDetail(arr, (left + index[i]).toInt(),
(left + index[i + 1] - 1).toInt(), r + 1, temp);
}
}
}

void main() {
List? arr = ["BCA", "CBAA", "AC", "BADFE", "ABC", "CBA"];
MSDSort.sort(arr);
for (String s in arr) {
print(s);
}
}
Loading

0 comments on commit 7acb29b

Please sign in to comment.