v8
This commit is contained in:
19
lib/v9/pages/sort/functions/bubble.dart
Normal file
19
lib/v9/pages/sort/functions/bubble.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///冒泡排序
|
||||
Future<void> bubbleSort(List<int> src, SortCallback callback ) async{
|
||||
//控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。
|
||||
for (int i = 0; i < src.length; ++i) {
|
||||
//遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。
|
||||
for (int j = 0; j < src.length - i - 1; ++j) {
|
||||
//如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。
|
||||
if (src[j] > src[j + 1]) {
|
||||
int temp = src[j];
|
||||
src[j] = src[j + 1];
|
||||
src[j + 1] = temp;
|
||||
}
|
||||
//实现一个延迟,以便在ui上展示排序的动画效果
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
lib/v9/pages/sort/functions/cocktail.dart
Normal file
52
lib/v9/pages/sort/functions/cocktail.dart
Normal file
@@ -0,0 +1,52 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///鸡尾酒排序(双向冒泡排序)
|
||||
Future<void> cocktailSort(List<int> src, SortCallback callback ) async {
|
||||
bool swapped = true; // 表示是否进行了交换
|
||||
int start = 0; // 当前未排序部分的起始位置
|
||||
int end = src.length; // 当前未排序部分的结束位置
|
||||
|
||||
// 开始排序循环,只有当没有进行交换时才会退出循环
|
||||
while (swapped == true) {
|
||||
swapped = false;
|
||||
|
||||
// 从左往右遍历需要排序的部分
|
||||
for (int i = start; i < end - 1; ++i) {
|
||||
// 对每两个相邻元素进行比较
|
||||
if (src[i] > src[i + 1]) {
|
||||
// 如果前面的元素大于后面的元素,则交换它们的位置
|
||||
int temp = src[i];
|
||||
src[i] = src[i + 1];
|
||||
src[i + 1] = temp;
|
||||
swapped = true; // 进行了交换
|
||||
}
|
||||
|
||||
// 实现动画效果,延迟一段时间后更新数组状态
|
||||
await callback(src);
|
||||
}
|
||||
|
||||
// 如果没有进行交换,则说明已经排好序,退出循环
|
||||
if (swapped == false) break;
|
||||
// 重设为false,准备进行下一轮排序
|
||||
swapped = false;
|
||||
// 将end设置为上一轮排序的最后一个元素的位置
|
||||
end = end - 1;
|
||||
|
||||
// 从右往左遍历需要排序的部分
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
// 对每两个相邻元素进行比较
|
||||
if (src[i] > src[i + 1]) {
|
||||
// 如果前面的元素大于后面的元素,则交换它们的位置
|
||||
int temp = src[i];
|
||||
src[i] = src[i + 1];
|
||||
src[i + 1] = temp;
|
||||
swapped = true; // 进行了交换
|
||||
}
|
||||
|
||||
// 实现动画效果,延迟一段时间后更新数组状态
|
||||
await callback(src);
|
||||
}
|
||||
// 将start向右移一位,准备下一轮排序
|
||||
start = start + 1;
|
||||
}
|
||||
}
|
||||
34
lib/v9/pages/sort/functions/comb.dart
Normal file
34
lib/v9/pages/sort/functions/comb.dart
Normal file
@@ -0,0 +1,34 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///梳排序(Comb Sort)
|
||||
Future<void> combSort(List<int> src, SortCallback callback) async{
|
||||
int gap = src.length;
|
||||
|
||||
bool swapped = true;
|
||||
|
||||
// 当间隔不为1或存在交换时执行循环
|
||||
while (gap != 1 || swapped == true) {
|
||||
// 通过缩小间隔来逐步将元素归位
|
||||
gap = getNextGap(gap);
|
||||
swapped = false;
|
||||
for (int i = 0; i < src.length - gap; i++) {
|
||||
// 如果当前元素大于间隔位置上的元素,则交换它们的位置
|
||||
if (src[i] > src[i + gap]) {
|
||||
int temp = src[i];
|
||||
src[i] = src[i + gap];
|
||||
src[i + gap] = temp;
|
||||
swapped = true;
|
||||
}
|
||||
|
||||
// 实现一个延迟,以便在 UI 上展示排序的动画效果。
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getNextGap(int gap) {
|
||||
// 根据当前间隔值计算下一个间隔值
|
||||
gap = (gap * 10) ~/ 13;
|
||||
if (gap < 1) return 1;
|
||||
return gap;
|
||||
}
|
||||
54
lib/v9/pages/sort/functions/cycle.dart
Normal file
54
lib/v9/pages/sort/functions/cycle.dart
Normal file
@@ -0,0 +1,54 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///循环排序
|
||||
Future<void> cycleSort(List<int> src, SortCallback callback) async {
|
||||
int writes = 0;
|
||||
for (int cycleStart = 0; cycleStart <= src.length - 2; cycleStart++) {
|
||||
int item = src[cycleStart];
|
||||
int pos = cycleStart;
|
||||
|
||||
// 在未排序部分中寻找比当前元素小的元素个数
|
||||
for (int i = cycleStart + 1; i < src.length; i++) {
|
||||
if (src[i] < item) pos++;
|
||||
}
|
||||
|
||||
// 如果当前元素已经在正确位置上,则跳过此次迭代
|
||||
if (pos == cycleStart) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 将当前元素放置到正确的位置上,并记录写操作次数
|
||||
while (item == src[pos]) {
|
||||
pos += 1;
|
||||
}
|
||||
if (pos != cycleStart) {
|
||||
int temp = item;
|
||||
item = src[pos];
|
||||
src[pos] = temp;
|
||||
writes++;
|
||||
}
|
||||
|
||||
// 循环将位于当前位置的元素放置到正确的位置上
|
||||
while (pos != cycleStart) {
|
||||
pos = cycleStart;
|
||||
// 继续在未排序部分中寻找比当前元素小的元素个数
|
||||
for (int i = cycleStart + 1; i < src.length; i++) {
|
||||
if (src[i] < item) pos += 1;
|
||||
}
|
||||
|
||||
// 将当前元素放置到正确的位置上,并记录写操作次数
|
||||
while (item == src[pos]) {
|
||||
pos += 1;
|
||||
}
|
||||
if (item != src[pos]) {
|
||||
int temp = item;
|
||||
item = src[pos];
|
||||
src[pos] = temp;
|
||||
writes++;
|
||||
}
|
||||
|
||||
// 添加延迟操作以展示排序过程
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
lib/v9/pages/sort/functions/gnome.dart
Normal file
22
lib/v9/pages/sort/functions/gnome.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///地精排序 (侏儒排序)
|
||||
Future<void> gnomeSort(List<int> src, SortCallback callback) async {
|
||||
int index = 0;
|
||||
while (index < src.length) {
|
||||
// 当 index 小于数组长度时执行循环
|
||||
if (index == 0) index++;
|
||||
if (src[index] >= src[index - 1]) {
|
||||
// 如果当前元素大于等于前面的元素,则将 index 加1
|
||||
index++;
|
||||
} else {
|
||||
// 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置)
|
||||
int temp = src[index];
|
||||
src[index] = src[index - 1];
|
||||
src[index - 1] = temp;
|
||||
index--;
|
||||
}
|
||||
await callback(src);
|
||||
}
|
||||
return;
|
||||
}
|
||||
38
lib/v9/pages/sort/functions/heap.dart
Normal file
38
lib/v9/pages/sort/functions/heap.dart
Normal file
@@ -0,0 +1,38 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///堆排序
|
||||
Future<void> heapSort(List<int> src, SortCallback callback) async {
|
||||
// 从最后一个非叶子节点开始,构建最大堆
|
||||
for (int i = src.length ~/ 2; i >= 0; i--) {
|
||||
await heapify(src,callback, src.length, i);
|
||||
}
|
||||
|
||||
// 依次取出最大堆的根节点(最大值),并进行堆化
|
||||
for (int i = src.length - 1; i >= 0; i--) {
|
||||
int temp = src[0];
|
||||
src[0] = src[i];
|
||||
src[i] = temp;
|
||||
await heapify(src, callback,i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> heapify(List<int> src, SortCallback callback, int n, int i) async{
|
||||
int largest = i;
|
||||
int l = 2 * i + 1; // 左子节点索引
|
||||
int r = 2 * i + 2; // 右子节点索引
|
||||
|
||||
// 如果左子节点存在并且大于父节点,则更新最大值索引
|
||||
if (l < n && src[l] > src[largest]) largest = l;
|
||||
|
||||
// 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引
|
||||
if (r < n && src[r] > src[largest]) largest = r;
|
||||
|
||||
// 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化
|
||||
if (largest != i) {
|
||||
int temp = src[i];
|
||||
src[i] = src[largest];
|
||||
src[largest] = temp;
|
||||
heapify(src,callback, n, largest);
|
||||
}
|
||||
await callback(src);
|
||||
}
|
||||
19
lib/v9/pages/sort/functions/insertion.dart
Normal file
19
lib/v9/pages/sort/functions/insertion.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///插入排序
|
||||
Future<void> insertionSort(List<int> src, SortCallback callback) async {
|
||||
for (int i = 1; i < src.length; i++) {
|
||||
int temp = src[i]; // 将当前元素存储到临时变量 temp 中
|
||||
int j = i - 1; // j 表示已排序部分的最后一个元素的索引
|
||||
|
||||
// 在已排序部分从后往前查找,找到合适位置插入当前元素
|
||||
while (j >= 0 && temp < src[j]) {
|
||||
src[j + 1] = src[j]; // 当前元素比已排序部分的元素小,将元素后移一位
|
||||
--j; // 向前遍历
|
||||
// 更新排序结果回调
|
||||
await callback(src);
|
||||
}
|
||||
src[j + 1] = temp; // 插入当前元素到已排序部分的正确位置
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
79
lib/v9/pages/sort/functions/merage.dart
Normal file
79
lib/v9/pages/sort/functions/merage.dart
Normal file
@@ -0,0 +1,79 @@
|
||||
import '../functions.dart';
|
||||
|
||||
//快速排序
|
||||
Future<void> mergeSort(List<int> src, SortCallback callback) async {
|
||||
await _mergeSort(src,callback,0,src.length-1);
|
||||
}
|
||||
|
||||
///归并排序
|
||||
Future<void> _mergeSort(List<int> src, SortCallback callback,int leftIndex, int rightIndex) async {
|
||||
// 定义一个名为 merge 的异步函数,用于合并两个有序子数组
|
||||
Future<void> merge(int leftIndex, int middleIndex, int rightIndex) async {
|
||||
// 计算左侧子数组和右侧子数组的大小
|
||||
int leftSize = middleIndex - leftIndex + 1;
|
||||
int rightSize = rightIndex - middleIndex;
|
||||
|
||||
// 创建左侧子数组和右侧子数组
|
||||
List leftList = List.generate(leftSize, (index) => 0);
|
||||
List rightList = List.generate(rightSize, (index) => 0);
|
||||
|
||||
// 将原始数组中的元素分别复制到左侧子数组和右侧子数组中
|
||||
for (int i = 0; i < leftSize; i++) {
|
||||
leftList[i] = src[leftIndex + i];
|
||||
}
|
||||
for (int j = 0; j < rightSize; j++) {
|
||||
rightList[j] = src[middleIndex + j + 1];
|
||||
}
|
||||
|
||||
// 初始化游标和索引
|
||||
int i = 0, j = 0;
|
||||
int k = leftIndex;
|
||||
|
||||
// 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中
|
||||
while (i < leftSize && j < rightSize) {
|
||||
if (leftList[i] <= rightList[j]) {
|
||||
src[k] = leftList[i];
|
||||
i++;
|
||||
} else {
|
||||
src[k] = rightList[j];
|
||||
j++;
|
||||
}
|
||||
|
||||
await callback(src);
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
// 将左侧子数组或右侧子数组中剩余的元素放入原始数组中
|
||||
while (i < leftSize) {
|
||||
src[k] = leftList[i];
|
||||
i++;
|
||||
k++;
|
||||
|
||||
await callback(src);
|
||||
}
|
||||
|
||||
while (j < rightSize) {
|
||||
src[k] = rightList[j];
|
||||
j++;
|
||||
k++;
|
||||
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果左索引小于右索引,则递归地对数组进行归并排序
|
||||
if (leftIndex < rightIndex) {
|
||||
// 计算中间索引位置
|
||||
int middleIndex = (rightIndex + leftIndex) ~/ 2;
|
||||
|
||||
// 分别对左侧子数组和右侧子数组进行归并排序
|
||||
await _mergeSort(src,callback,leftIndex, middleIndex);
|
||||
await _mergeSort(src,callback,middleIndex + 1, rightIndex);
|
||||
|
||||
await callback(src);
|
||||
|
||||
// 合并两个有序子数组
|
||||
await merge(leftIndex, middleIndex, rightIndex);
|
||||
}
|
||||
}
|
||||
37
lib/v9/pages/sort/functions/oddEven.dart
Normal file
37
lib/v9/pages/sort/functions/oddEven.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///奇偶排序(Odd-Even Sort)
|
||||
Future<void> oddEvenSort(List<int> src, SortCallback callback) async {
|
||||
bool isSorted = false;
|
||||
|
||||
while (!isSorted) {
|
||||
// 当 isSorted 为 false 时执行循环
|
||||
isSorted = true; // 先假设数组已经排好序
|
||||
|
||||
for (int i = 1; i <= src.length - 2; i = i + 2) {
|
||||
// 对奇数索引位置进行比较
|
||||
if (src[i] > src[i + 1]) {
|
||||
// 如果当前元素大于后面的元素,则交换它们的值
|
||||
int temp = src[i];
|
||||
src[i] = src[i + 1];
|
||||
src[i + 1] = temp;
|
||||
isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i <= src.length - 2; i = i + 2) {
|
||||
// 对偶数索引位置进行比较
|
||||
if (src[i] > src[i + 1]) {
|
||||
// 如果当前元素大于后面的元素,则交换它们的值
|
||||
int temp = src[i];
|
||||
src[i] = src[i + 1];
|
||||
src[i + 1] = temp;
|
||||
isSorted = false;
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
33
lib/v9/pages/sort/functions/pigeonHole.dart
Normal file
33
lib/v9/pages/sort/functions/pigeonHole.dart
Normal file
@@ -0,0 +1,33 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///鸽巢排序
|
||||
Future<void> pigeonHoleSort(List<int> src, SortCallback callback ) async{
|
||||
int min = src[0];
|
||||
int max = src[0];
|
||||
int range, i, j, index;
|
||||
|
||||
// 找到数组中的最大值和最小值
|
||||
for (int a = 0; a < src.length; a++) {
|
||||
if (src[a] > max) max = src[a];
|
||||
if (src[a] < min) min = src[a];
|
||||
}
|
||||
|
||||
// 计算鸽巢的个数
|
||||
range = max - min + 1;
|
||||
List<int> p = List.generate(range, (i) => 0);
|
||||
|
||||
// 将数字分配到各个鸽巢中
|
||||
for (i = 0; i < src.length; i++) {
|
||||
p[src[i] - min]++;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
|
||||
// 将鸽巢中的数字取出,重新放回到数组中
|
||||
for (j = 0; j < range; j++) {
|
||||
while (p[j]-- > 0) {
|
||||
src[index++] = j + min;
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
lib/v9/pages/sort/functions/quick.dart
Normal file
65
lib/v9/pages/sort/functions/quick.dart
Normal file
@@ -0,0 +1,65 @@
|
||||
import '../functions.dart';
|
||||
|
||||
//快速排序
|
||||
Future<void> quickSort(List<int> src, SortCallback callback) async {
|
||||
await _quickSort(src,callback,0,src.length-1);
|
||||
}
|
||||
|
||||
///快速排序
|
||||
Future<void> _quickSort(List<int> src, SortCallback callback,int leftIndex,int rightIndex) async {
|
||||
// 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置
|
||||
Future<int> _partition(int left, int right) async {
|
||||
// 选择中间位置的元素作为基准元素
|
||||
int p = (left + (right - left) / 2).toInt();
|
||||
|
||||
// 交换基准元素和最右边的元素
|
||||
var temp = src[p];
|
||||
src[p] = src[right];
|
||||
src[right] = temp;
|
||||
await callback(src);
|
||||
|
||||
// 初始化游标 cursor
|
||||
int cursor = left;
|
||||
|
||||
// 遍历数组并根据基准元素将元素交换到左侧或右侧
|
||||
for (int i = left; i < right; i++) {
|
||||
if (cf(src[i], src[right]) <= 0) {
|
||||
// 如果当前元素小于等于基准元素,则交换它和游标位置的元素
|
||||
var temp = src[i];
|
||||
src[i] = src[cursor];
|
||||
src[cursor] = temp;
|
||||
cursor++;
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
|
||||
// 将基准元素放置在游标位置
|
||||
temp = src[right];
|
||||
src[right] = src[cursor];
|
||||
src[cursor] = temp;
|
||||
|
||||
await callback(src);
|
||||
|
||||
return cursor; // 返回基准元素的索引位置
|
||||
}
|
||||
|
||||
// 如果左索引小于右索引,则递归地对数组进行快速排序
|
||||
if (leftIndex < rightIndex) {
|
||||
int p = await _partition(leftIndex, rightIndex);
|
||||
|
||||
await _quickSort(src,callback,leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序
|
||||
|
||||
await _quickSort(src,callback, p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序
|
||||
}
|
||||
}
|
||||
|
||||
// 比较函数,用于判断两个元素的大小关系
|
||||
cf(int a, int b) {
|
||||
if (a < b) {
|
||||
return -1; // 若 a 小于 b,则返回 -1
|
||||
} else if (a > b) {
|
||||
return 1; // 若 a 大于 b,则返回 1
|
||||
} else {
|
||||
return 0; // 若 a 等于 b,则返回 0
|
||||
}
|
||||
}
|
||||
18
lib/v9/pages/sort/functions/selection.dart
Normal file
18
lib/v9/pages/sort/functions/selection.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///选择排序
|
||||
Future<void> selectionSort(List<int> src, SortCallback callback ) async {
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
for (int j = i + 1; j < src.length; j++) {
|
||||
// 遍历未排序部分,内层循环控制变量 j
|
||||
if (src[i] > src[j]) {
|
||||
// 判断当前元素是否比后续元素小
|
||||
int temp = src[j];
|
||||
// 交换当前元素和后续较小的元素
|
||||
src[j] = src[i];
|
||||
src[i] = temp;
|
||||
}
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
lib/v9/pages/sort/functions/shell.dart
Normal file
21
lib/v9/pages/sort/functions/shell.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import '../functions.dart';
|
||||
|
||||
///希尔排序
|
||||
Future<void> shellSort(List<int> src, SortCallback callback) async{
|
||||
//定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。
|
||||
for (int gap = src.length ~/ 2; gap > 0; gap ~/= 2) {
|
||||
//遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。
|
||||
for (int i = gap; i < src.length; i += 1) {
|
||||
//将当前遍历到的元素赋值给它
|
||||
int temp = src[i];
|
||||
//内部使用一个 for 循环来实现插入排序。
|
||||
//循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。
|
||||
int j;
|
||||
for (j = i; j >= gap && src[j - gap] > temp; j -= gap) {
|
||||
src[j] = src[j - gap];
|
||||
}
|
||||
src[j] = temp;
|
||||
await callback(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user