【ZZULI数据结构实验四】:C语言排序算法大比拼

在这里插入图片描述

📃博客主页: 小镇敲码人
💚代码仓库,欢迎访问
🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏
🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎
❤️ 什么?你问我答案,少年你看,下一个十年又来了 💞 💞 💞

【ZZULI数据结构实验四】:C语言排序算法大比拼

  • 🪡 实验的内容和要求
  • 🪡 结构设计及函数接口
  • 🪡 排序函数的具体实现
    • 🚵🏻‍♀️ 冒泡排序的实现
    • 🚵🏻‍♀️ 选择排序的实现
    • 🚵🏻‍♀️ 直接插入排序的实现
    • 🚵🏻‍♀️ 折半插入排序的实现
      • 🍟 OJ测试
    • 🚵🏻‍♀️ 希尔排序
    • 🚵🏻‍♀️ 堆排序
    • 🚵🏻‍♀️ 快速排序
      • 🍟 递归版本
      • 🍟 非递归版本
  • 🪡 测试及结果演示
    • 🚵🏻‍♀️ 菜单函数
    • 🚵🏻‍♀️ 正确性测试及中间结果打印
    • 🚵🏻‍♀️ 稳定性测试
    • 🚵🏻‍♀️ 性能测试

前言:本篇博客不讲具体的排序算法原理,如果你对某个排序算法的原理不太理解,请看博主这篇博客八大排序C语言实现,以下排序的代码的正确性都在上篇博客八大排序中进行过OJ测试,不做100%保证,但是大概率应该是没什么问题,如有问题,敬请斧正。

🪡 实验的内容和要求

在这里插入图片描述

🪡 结构设计及函数接口

实验要求里面要求我们判断排序的算法稳定性,我们需要保存初始时每个数据对应的下标,即把数据和初始时的下标用结构体绑在一起,这里具体的原理我们等会再解释:

typedef int DataType;
typedef struct DataNode
{DataType data_;//数据的值int idx;//数组开始时的下标}Node;

各种函数接口:

// 交换函数
void Swap(Node* a, int* b);
//打印数组
void PrintArr(Node* a, int n);
// 直接插入排序
void InsertSort(Node* a, int n);//折半插入排序
void BinInsertSort(Node* a, int n);// 希尔排序
void ShellSort(Node* a, int n);// 选择排序
void SelectSort(Node* a, int n);// 堆排序
void AdjustDown(Node* a, int n, int root);
void HeapSort(Node* a, int n);// 冒泡排序
void BubbleSort(Node* a, int n);// 快速排序递归实现
// 快速排序hoare版本
int PartSort1(Node* a, int left, int right,int n);void QuickSort(Node* a, int left, int right,int n);//快速排序递归实现
// 快速排序 非递归实现
void QuickSortNonR(Node* a, int left, int right,int n);bool is_stable(Node* a, int n);//判断某个排序算法是否是稳定的

🪡 排序函数的具体实现

🚵🏻‍♀️ 冒泡排序的实现

// 冒泡排序
void BubbleSort(Node* a, int n)
{int flag = 0;//设置标志变量优化int cnt = 0;for (int i = 0; i < n - 1; i++)//排序n个数,需要n-1趟{flag = 0;for (int j = 0; j < n - i - 1; j++){if (a[j].data_ > a[j + 1].data_)//如果满足交换条件交换{cnt++;flag = 1;//如果存在交换,将flag设置为1Swap(&a[j], &a[j + 1]);}}//printf("第%d躺排序结果:", i);//PrintArr(a, n);if (flag == 0)//如果这一趟没有数交换说明已经有序,结束排序{break;}}printf("BubbleSort:\n");printf("比较和交换的次数为:%d\n", cnt);
}

🚵🏻‍♀️ 选择排序的实现

// 选择排序
void SelectSort(Node* a, int n)
{int k = 0;int j = 0;int mini = 0;//创建变量,保存当前最小值的下标int cnt = 0;int cnt1 = 0;for (int i = 0; i < n - 1; i++)//n-1趟就排完了{mini = i;for (j = i; j < n; j++){if (a[mini].data_ > a[j].data_)//找出目前最小的元素下标{cnt++;mini = j;}}if (mini != i)//如果这个下标不是i位置,就交换{Swap(&a[mini], &a[i]);cnt1++;}//printf("第%d躺排序结果:", k++);//PrintArr(a, n);}printf("SelectSort:\n");printf("比较的次数为: %d\n", cnt);printf("交换的次数为: %d\n", cnt1);
}

🚵🏻‍♀️ 直接插入排序的实现

// 插入排序
void InsertSort(Node* a, int n)
{//0~end有序int end = 0;int i = 0;int cnt = 0;int cnt1 = 0;while (end < n - 1){Node tmp = a[end + 1];//插入位置的元素for (i = end; i >= 0; i--)//调整其到正确位置,将大于tmp的都往整体后挪动一位,然后插入tmp{if (a[i].data_ > tmp.data_){cnt++;cnt1++;a[i + 1] = a[i];}else{cnt++;break;}}cnt1++;a[i + 1] = tmp;end++;//printf("第%d躺排序结果:", end);//PrintArr(a, n);}printf("InsertSort:\n");printf("比较的次数为: %d\n", cnt);printf("挪动数据次数为: %d\n", cnt1);
}

🚵🏻‍♀️ 折半插入排序的实现

这里对这个之前没有阐述过的排序的原理做一下阐述:折半插入排序算法是对直接插入排序的一个小优化,它加入了二分算法(也叫折半查找算法),可以快速的找出我们每一次需要插入的位置( l o g N logN logN的量级),但是挪动数据部分的时间效率和直接插入排序一样,所以整体性能提升不大,还 O ( N 2 ) O(N^2) O(N2)的量级。

代码实现:

//折半插入排序
void BinInsertSort(Node* a, int n)
{//0~end有序int end = 0;int i = 0;int cnt = 0;int cnt1 = 0;while (end < n - 1){Node tmp = a[end + 1];//插入位置的元素//开始二分查找int left = 0, right = end;int pos = end+1;//保存满足要求的下标while (left <= right){int mid = left + ((right - left) >> 2);if (a[mid].data_ <= tmp.data_){cnt++;left = mid + 1;}else if(a[mid].data_ > tmp.data_){cnt++;pos = mid;right = mid - 1;}}//把pos位置及其之后的数据往后挪一位for (int i = end; i >= pos; --i){cnt1++;a[i + 1] = a[i];}cnt1++;a[pos] = tmp;end++;//printf("第%d躺排序结果:", end);//PrintArr(a, n);}printf(" BinInsertSort:\n");printf("比较的次数为: %d\n", cnt);printf("挪动数据次数为: %d\n", cnt1);
}

🍟 OJ测试

之前没有对这个代码的正确性做过测试,现在我们借助这个OJ题来测试一下:

在这里插入图片描述

可以看到卡到了第12个数据,直接插入排序的测试情况和它一致,所以效率上并没有太大提升,注意要把Node类型改为int。可以基本认为我们的折半排序算法是正确的。

🚵🏻‍♀️ 希尔排序

// 希尔排序
void ShellSort(Node* a, int n)
{int gap = n;//令gap等于nint i = 0;//i为控制每次插入排序的开始的位置的变量int j = 0;//j为每次直接插入排序的变量int cnt = 0;int cnt1 = 0;int k = 0;while (gap > 1){gap = gap / 3 + 1;//gap不为一个固定的值,预处理多次,让我们的分组插入的效果更加好,降低后面直接插入的时间for (i = 0; i < n - gap; i++)//gap为某一个值时的分组插入,这里我们使用多组同时走插入排序{int end = i;Node tmp = a[end + gap];for (j = end; j >= 0; j -= gap){if (tmp.data_ < a[j].data_)//小于就把大的值往后移{cnt++;cnt1++;a[j + gap] = a[j];}else//找到了,break{cnt++;break;}}cnt1++;a[j + gap] = tmp;//将tmp赋值给正确位置}//printf("第%d躺排序结果:",k++);//PrintArr(a, n);}printf("ShellSort:\n");printf("比较的次数为: %d\n", cnt);printf("挪动数据次数为: %d\n", cnt1);
}

🚵🏻‍♀️ 堆排序

// 向下调整
void AdjustDown(Node* a, int n, int root,int* cnt,int* cnt1)
{int child = root * 2 + 1;while (child < n){if (child + 1 < n && a[child].data_ < a[child + 1].data_)//找出最大的孩子{(*cnt)++;child = child + 1;}if (a[root].data_ < a[child].data_)//如果根节点的值比最大的孩子小就交换{(*cnt)++;(*cnt1)++;Swap(&a[root], &a[child]);root = child;child = root * 2 + 1;}else//否则调整完成{cnt++;break;}}
}
//堆排序,大堆,排升序
void HeapSort(Node* a, int n)
{assert(a);int cnt = 0;int cnt1 = 0;for (int i = (n - 1 - 1) / 2; i >= 0; i--)//我们向上调整,原地建一个大堆{AdjustDown(a, n, i,&cnt,&cnt1);}int i = 0;//将大堆最大的和最后一个元素交换,并向下调整for (int end = n - 1; end >= 0; --end){cnt1++;Swap(&a[0], &a[end]);//将堆顶元素放到堆最后面去AdjustDown(a, end, 0,&cnt,&cnt1);//此时的end就代表我们的元素个数//printf("第%d躺排序结果:", i++);//PrintArr(a,n);}printf("HeapSort:\n");printf("比较的次数为: %d\n", cnt);printf("交换的次数为: %d\n", cnt1);
}

🚵🏻‍♀️ 快速排序

🍟 递归版本

// 快速排序递归实现
// 快速排序hoare版本
int get_mid(Node* a, int left, int right)
{int mid = (left + right) / 2;//中间下标的数if (a[left].data_ < a[mid].data_)//如果left位置的值小于mid位置的值{if (a[mid].data_ < a[right].data_)//如果right位置的值大于mid位置的值,那么mid位置的值就是第2大的(中位数){return mid;}else if (a[left].data_ > a[right].data_)//left位置的值大于right位置的值,mid是最大的{return left;}elsereturn right;}else//a[left] >= a[mid]{if (a[mid].data_ > a[right].data_)//mid位置的值大于right位置的值return mid;else if (a[left].data_ < a[right].data_)//left不是最大的return left;elsereturn right;}
}int k = 0;
int PartSort1(Node* a, int left, int right,int n)
{int mid = get_mid(a, left, right);//三数取中找中位数Swap(&a[mid], &a[left]);//交换int keyi = left;//记录关键元素的位置,方便最后的交换while (left < right)//如果left < right就退出循环{while (left < right && a[right].data_ >= a[keyi].data_)//先找小(严格找小),也要加上left < right的条件,防止越界 {right--;}while (left < right && a[left].data_ <= a[keyi].data_)//再找大(严格找大),同样的越界条件要加上{left++;}Swap(&a[left], &a[right]);//找到了交换}Swap(&a[keyi], &a[left]);//最后交换keyi元素和最后一个小的元素的位置,这样单趟就排完了,keyi位置的元素到了正确位置,不用管它了//printf("第%d躺排序结果:",k++);//PrintArr(a,n);return left;
}void QuickSort(Node* a, int left, int right,int n)
{if (left >= right)//一个元素或者区间不存在的情况递归就结束return;int i = 0;int mid = PartSort1(a, left, right,n);//[left,mid-1] mid [mid+1,right]QuickSort(a, left, mid - 1,n);//继续递归左边,执行相同的单趟排序的思路QuickSort(a, mid + 1, right,n);//继续递归右边,执行相同的单趟排序的思路
}

🍟 非递归版本

非递归版本需要栈来辅助,代码已经放在文章开头。

int k = 0;
int PartSort1(Node* a, int left, int right,int n)
{int mid = get_mid(a, left, right);//三数取中找中位数Swap(&a[mid], &a[left]);//交换int keyi = left;//记录关键元素的位置,方便最后的交换while (left < right)//如果left < right就退出循环{while (left < right && a[right].data_ >= a[keyi].data_)//先找小(严格找小),也要加上left < right的条件,防止越界 {right--;}while (left < right && a[left].data_ <= a[keyi].data_)//再找大(严格找大),同样的越界条件要加上{left++;}Swap(&a[left], &a[right]);//找到了交换}Swap(&a[keyi], &a[left]);//最后交换keyi元素和最后一个小的元素的位置,这样单趟就排完了,keyi位置的元素到了正确位置,不用管它了//printf("第%d躺排序结果:",k++);//PrintArr(a,n);return left;
}// 快速排序 非递归实现     
void QuickSortNonR(Node* a, int left, int right,int n)
{Stack ps;//创建栈对象StackInit(&ps);//初始化栈对象StackPush(&ps, right);//入根节点的区间值,先入右,再入左,这样我们拿的时候就可以先拿到左StackPush(&ps, left);while (!StackEmpty(&ps))//如果栈为空,排序完成{int left1 = StackTop(&ps);//拿到栈顶区间的左边边界StackPop(&ps);//pop掉左边边界int right1 = StackTop(&ps);//拿到栈顶区间的左边边界StackPop(&ps);//pop掉右边边界int mid = PartSort1(a, left1, right1,n);//走一趟快速排序,哪个版本都可以,这里我们用的前后指针if (right1 > mid + 1)//先入右边区间,如果右边区间存在且长度不为1的话{StackPush(&ps, right1);StackPush(&ps, mid + 1);}if (left1 < mid - 1)//再入左边区间,如果左边区间存在且长度不为1的话{StackPush(&ps, mid - 1);StackPush(&ps, left1);}}StackDestroy(&ps);//销毁栈
}

🪡 测试及结果演示

注意:由于快速排序递归版本需要从外面传一个变量(使用指针)进来才便于统计比较和交换的次数,所以只有这个排序我们没有打印比较和交换次数,如果你不嫌麻烦,在外面的接口打印也是可以的。

🚵🏻‍♀️ 菜单函数

#include"sort.h"void Test1()
{printf("请输入要测试的数据的个数: \n");int n = 0;scanf("%d", &n);Node* a = (Node*)malloc(sizeof(Node) * n);Node* tmp = (Node*)malloc(sizeof(Node) * n);printf("请输入要测试的数据: \n");for (int i = 0; i < n; ++i){scanf("%d", &a[i].data_);a[i].idx = i;}printf("请输入你想测试的排序:\n");while (1){printf("****************************************************************\n");printf("**********************1.BubbleSort *****************************\n");printf("**********************2.InsertSort *****************************\n");printf("**********************3.BinInsertSort **************************\n");printf("**********************4.ShellSort*******************************\n");printf("**********************5.SelectSort******************************\n");printf("**********************6.HeapSort********************************\n");printf("**********************7.QuickSort ******************************\n");printf("**********************8.QuickSortNonR **************************\n");printf("**********************9.return        **************************\n");printf("****************************************************************\n");int b = 0;scanf("%d", &b);switch (b){case 1: {memcpy(tmp,a,sizeof(Node)* n);    BubbleSort(tmp, n);}break;case 2: {memcpy(tmp, a, sizeof(Node) * n);InsertSort(tmp, n); }break;case 3: {memcpy(tmp, a, sizeof(Node) * n);BinInsertSort(tmp, n); }break;case 4: {memcpy(tmp, a, sizeof(Node) * n);ShellSort(tmp, n); }break;case 5: {memcpy(tmp, a, sizeof(Node) * n);SelectSort(tmp, n); }break;case 6: {memcpy(tmp, a, sizeof(Node) * n);HeapSort(tmp, n); }break;case 7: {memcpy(tmp, a, sizeof(Node) * n);QuickSort(tmp,0,n-1,n); }break;case 8: {memcpy(tmp, a, sizeof(Node) * n);QuickSortNonR(tmp,0,n-1,n);}break;case 9: return;break;default:printf("输入错误,请重新输入\n");break;}}
}void Test2()
{srand(time(NULL));int N = 100000;printf("N: %d\n", N);Node* a1 = (Node*)malloc(sizeof(Node) * N);if (a1 == NULL){printf("a1 malloc failed\n");exit(-1);}Node* a2 = (Node*)malloc(sizeof(Node) * N);if (a2 == NULL){printf("a2 malloc failed\n");exit(-1);}Node* a3 = (Node*)malloc(sizeof(Node) * N);if (a3 == NULL){printf("a3 malloc failed\n");exit(-1);}Node* a4 = (Node*)malloc(sizeof(Node) * N);if (a4 == NULL){printf("a4 malloc failed\n");exit(-1);}Node* a5 = (Node*)malloc(sizeof(Node) * N);if (a5 == NULL){printf("a5 malloc failed\n");exit(-1);}Node* a6 = (Node*)malloc(sizeof(Node) * N);if (a6 == NULL){printf("a6 malloc failed\n");exit(-1);}Node* a7 = (Node*)malloc(sizeof(Node) * N);if (a7 == NULL){printf("a7 malloc failed\n");exit(-1);}Node* a8 = (Node*)malloc(sizeof(Node) * N);if (a8 == NULL){printf("a8 malloc failed\n");exit(-1);}for (int i = 0; i < N; ++i){a1[i].data_ = rand() % N+i;a1[i].idx = i;a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];a8[i] = a1[i];}InsertSort(a1,N);bool flag1 = is_stable(a1,N);BinInsertSort(a2, N);bool flag2 = is_stable(a2,N);BubbleSort(a3,N);bool flag3 = is_stable(a3,N);SelectSort(a4, N);bool flag4 = is_stable(a4,N);ShellSort(a5, N);bool flag5 = is_stable(a5,N);QuickSort(a6, 0, N - 1, N);bool flag6 = is_stable(a6,N);HeapSort(a7, N);bool flag7 = is_stable(a7,N);QuickSortNonR(a8, 0, N - 1, N);bool flag8 = is_stable(a8, N);printf("InsertSort stability:\n");if (flag1)printf("Yes\n");elseprintf("No\n");printf("BinInsertSort stability:\n");if (flag2)printf("Yes\n");elseprintf("No\n");printf("BubbleSort stability:\n");if (flag3)printf("Yes\n");elseprintf("No\n");printf("SelectSort stability:\n");if (flag4)printf("Yes\n");elseprintf("No\n");printf("ShellSort stability:\n");if (flag5)printf("Yes\n");elseprintf("No\n");printf("QuickSort stability:\n");if (flag6)printf("Yes\n");elseprintf("No\n");printf("HeapSort stability:\n");if (flag7)printf("Yes\n");elseprintf("No\n");printf("QuickSortNonR stability:\n");if (flag8)printf("Yes\n");elseprintf("No\n");
}void Test3()
{srand(time(NULL));int N = 100000;printf("N: %d\n", N);Node* a1 = (Node*)malloc(sizeof(Node) * N);if (a1 == NULL){printf("a1 malloc failed\n");exit(-1);}Node* a2 = (Node*)malloc(sizeof(Node) * N);if (a2 == NULL){printf("a2 malloc failed\n");exit(-1);}Node* a3 = (Node*)malloc(sizeof(Node) * N);if (a3 == NULL){printf("a3 malloc failed\n");exit(-1);}Node* a4 = (Node*)malloc(sizeof(Node) * N);if (a4 == NULL){printf("a4 malloc failed\n");exit(-1);}Node* a5 = (Node*)malloc(sizeof(Node) * N);if (a5 == NULL){printf("a5 malloc failed\n");exit(-1);}Node* a6 = (Node*)malloc(sizeof(Node) * N);if (a6 == NULL){printf("a6 malloc failed\n");exit(-1);}Node* a7 = (Node*)malloc(sizeof(Node) * N);if (a7 == NULL){printf("a7 malloc failed\n");exit(-1);}Node* a8 = (Node*)malloc(sizeof(Node) * N);if (a8 == NULL){printf("a8 malloc failed\n");exit(-1);}for (int i = 0; i < N; ++i){a1[i].data_ = rand() % N;a1[i].idx = i;a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];a8[i] = a1[i];}int begin1 = clock();BubbleSort(a1, N);int end1 = clock();int begin2 = clock();SelectSort(a2, N);int end2 = clock();int begin3 = clock();InsertSort(a3, N);int end3 = clock();int begin4 = clock();HeapSort(a4, N);int end4 = clock();int begin5 = clock();QuickSort(a5, 0, N - 1,N);//三路划分版本int end5 = clock();int begin6 = clock();ShellSort(a6, N);int end6 = clock();int begin7 = clock();BinInsertSort(a7, N);int end7 = clock();int begin8 = clock();QuickSortNonR(a8,0,N-1,N);int end8 = clock();printf("BubbleSort:%dms\n", end1 - begin1);printf("SelectSort:%dms\n", end2 - begin2);printf("InsertSort:%dms\n", end3 - begin3);printf("HeapSort:%dms\n", end4 - begin4);printf("QuickSort :%dms\n", end5 - begin5);printf("ShellSort:%dms\n", end6 - begin6);printf("BinInsertSort:%dms\n", end7 - begin7);printf("QuickSortNonR:%dms\n", end8 - begin8);}
void menu()
{printf("请输入你要测试的排序项目:\n");while (1){printf("**********************************************************\n");printf("**********************1.正确性测试************************\n");printf("**********************2.稳定性测试************************\n");printf("**********************3.性能测试**************************\n");printf("**********************4.退出程序**************************\n");printf("**********************************************************\n");int a = 0;scanf("%d", &a);switch(a){case 1: Test1();break;case 2: Test2();break;case 3: Test3();break;case 4: exit(-1);break;default:printf("输入错误,请重新输入\n");break;}}
}
int main()
{menu();return 0;
}

🚵🏻‍♀️ 正确性测试及中间结果打印

其实正确性的测试我们已经使用OJ题测试过了,这里再做一次是为了迎合实验的需要,数据量较小的时候,可以把打印中间结果的注释拿掉,但是等会测试性能和排序算法稳定性时一定要记得把这个给注释掉,因为IO打印是很耗时间的,不知道要等到什么时候去。

数据:第一行是数组的个数,第二行是数据。

10
1  12 3 0 0 77 34 100 99 44

测试结果:

在这里插入图片描述

🚵🏻‍♀️ 稳定性测试

稳定性测试函数:

bool is_stable(Node* a, int n)
{for (int i = 0; i < n; ++i){for (int j = i + 1; j < n; ++j){if (a[i].data_ == a[j].data_ && a[i].idx > a[j].idx)return false;}}return true;
}

稳定性测试的原理是:先使用结构体保存数组开始的值对应的下标,然后排序之后,看相等的值之间的先后顺序有没有发生变化,从0下标开始,去找它后面相等的值,如果这个值的初始下标在它的前面,说明这个排序算法就是不稳定的。

稳定性测试的结果:(我们造了10w个数据,这么大的数据量足以说明真相,而且我们的值是随机值,因为随机值函数只能生成3w多个,所以我们给它的后面+i,尽量减少重复)

注意:要把打印中间结果代码的注释掉,可能会有些算法的交换或者比较次数变成负数,这是正常的,因为int的返回最大只有2^31-1, O ( N 2 ) O ( N^2 ) O(N2) 的算法数据量一大,是完全可能超过这个范围的,溢出了自然就变成负数了,我们不用管。

10w个数据测试:

在这里插入图片描述
与预期结果一致。

🚵🏻‍♀️ 性能测试

我们都测试重复值较少的情况。

  1. 10w个数据:

在这里插入图片描述

这是重复值较少的情况,重复值较多时,交换类的排序效率会慢很多:

在这里插入图片描述

重复值较多的情况下,可以发现对我们交换类的排序是不友好的,比较直观的是冒泡排序,时间来到了惊人的15秒。重复值较多时,有些交换类的排序交换和比较的次数都溢出了(重复值较少时没有溢出)。

同时也可以看出折半插入排序比直接插入排序的优势在于比较的次数大大减少,但是挪动的次数基本没变。

在这里插入图片描述

  1. 100w个数据
    数据量太大,我们把 O ( N 2 ) O ( N^2) O(N2)量级的排序给关掉,同样也是重复值较少的情况:

在这里插入图片描述

  1. 1000w个数据

运行结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分离式光电液位传感器与浮球开关相比具有哪些优势

分离式光电液位传感器与浮球开关相比有哪些优势&#xff1f;分离式光电液位传感器依据光学原理&#xff0c;在传统光学传感器的基础上进行了改进。其特点是将光学组件分离出来&#xff0c;置于水箱外部感应&#xff0c;而传感器本身则独立于水箱外。这种设计有效解决了浮球开关…

【智能算法】花斑翠鸟优化算法(PKO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;A Bouaouda受到自然界中花斑翠鸟社会行为启发&#xff0c;提出了花斑翠鸟优化算法&#xff08;Pied Kingfisher Optimizer, PKO&#xff09;。 2.算法原理 2.1算法思想…

mac安装nigix

1. 查看是否存在 nginx 执行brew search nginx 命令查询要安装的软件是否存在 brew search nginx 2. 安装nginx brew install nginx 3. 查看版本 nginx -v 4. 查看信息 查看ngxin下载的位置以及nginx配置文件存放路径等信息 brew info nginx 下载的存放路径 /usr/loca…

Renesas MCU之使用Keil搭建开发环境

目录 概述 1 软件安装 1.1 软件版本信息 1.2 安装FSP 1.3 安装和配置Keil 2 使用FSP创建工程 2.1 FSP中配置参数 2.2 配置板卡硬件资源 3 Keil中配置项目 3.1 在Keil配置FSP 3.2 添加user src目录 3.3 配置下载项 3.4 测试下载功能 4 使用stm32 NUCLEO板卡的ST-L…

elementplu父级页面怎么使用封装子组件原组件的方法

一、使用原因&#xff1a; 封装了el-table&#xff0c;表格中有多选&#xff0c;父级要根据指定状态&#xff0c;让其选择不上&#xff0c;需要用到elementplus中table原方法toggleRowSelection 附加小知识点&#xff1a;&#xff08;el-tree刷新树后之前选中的保持高亮setCurr…

11.6 归并排序

目录 11.6 归并排序 11.6.1 算法流程 11.6.2 算法特性 11.6.3 链表排序 11.6 归并排序 归并排序&#xff08;merge sort&#xff09;是一种基于分治策略的排序算法&#xff0c;包含图 11-10 所示的“划分”和“合并”阶段。 划分阶段&#xff1a;通过递归不断地…

雷池WAF-动态防护新功能体验

雷池WAF 雷池WAF&#xff08;Web Application Firewall&#xff0c;网络应用防火墙&#xff09;是由长亭科技开发的一个网络安全产品&#xff0c;它专注于保护Web应用免受黑客攻击。 今天主要讲的是长亭雷池最近新出的功能&#xff1a;动态防护 安装 雷池WAF支持多种安装方式…

Activiti7 Maven笔记

通过maven完成BPMN的创建,定义流程,部署流程,完成流程等操作 代码整合创建maven项目添加log4j日志配置添加activiti配置文件创建数据库 activitijava类编写程序生成表如果代码运行,没有生成表,可能是没有读取到activiti的配置文件 Activiti数据表介绍类关系图工作流引擎创建默认…

Windows主机信息收集

一、内网环境分析 1、什么是内网渗透 内网渗透: ①在拿到webshell的时候&#xff0c;想办法获得系统信息拿到系统权限&#xff0c;进入到网络系统内部之后收集内部 网络的各种信息&#xff0c;获取内部网络有价值的人员、资产信息。 ②内网渗透的第一步&#xff0c;内网信…

嵌入式linux中线程编程实现详解

大家好,今天主要给大家分享一下,线程的使用,通过具体的实例代码来说明一个线程创建到退出到回收的基本流程,后半部分则会通过实例来说明如何能够控制好线程,从临界资源访问与线程的执行顺序控制上引出互斥锁、信号量的概念与使用方法。 第一:为什么要使用线程 场景分析:…

[数据集][目标检测]电力工地场景下的人头检测数据集VOC+YOLO格式7035张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;7035 标注数量(xml文件个数)&#xff1a;7035 标注数量(txt文件个数)&#xff1a;7035 标注…

Dockershim 与 Containerd:两种容器运行时的故事

在不断发展的容器化世界中&#xff0c;两个关键组件经常被混淆&#xff1a;Dockershim 和 containerd。虽然它们在管理容器方面都发挥着重要作用&#xff0c;但它们的用途却截然不同。本文深入探讨了它们的功能&#xff0c;深入探讨了 Dockershim 和 containerd 之间的区别。 揭…

SpringBoot——全局异常处理

目录 异常 项目总结 新建一个SpringBoot项目 pom.xml Result&#xff08;通用的响应结果类&#xff09; MyBusinessException自定义异常类 GlobalExceptionHandler全局异常处理类 ExceptionController控制器 SpringbootExceptionApplication启动类 参考文章&#xff1a…

对比投入高成本自研推广系统,直接采用SaaS更有效益

推广分销作为一种有效的市场拓展方式&#xff0c;被越来越多的企业所采纳。部分企业会选择投入资源自研一套推广分销系统&#xff0c;但是其实最后发现几年过去了&#xff0c;投入了大量成本&#xff0c;系统仍然是一地鸡毛&#xff0c;还在定义一些基本的属性。 自研推广系统…

基于4G工业路由器的信息发布系统物联网应用方案

随着物联网技术的快速发展&#xff0c;智能信息发布系统已成为城市管理和信息传播的重要工具。而4G工业路由器作为连接信息发布终端与云平台的关键设备&#xff0c;其在提升信息发布效率方面发挥着至关重要的作用。为了提升智能信息发布系统的效率和智能化水平&#xff0c;智联…

【RPG Maker MV 仿新仙剑 战斗场景UI (十)】

RPG Maker MV 仿新仙剑 战斗场景UI &#xff08;十&#xff09; 前言角色站位人物站位人物影子 前言 上一期完成了几个功能&#xff0c;虽然没有进行进一步的优化&#xff0c;但基础的功能已经完成&#xff0c;现在记录下已完成及未完成的功能&#xff1a; 战斗菜单 一级战斗菜…

PromptIR论文阅读笔记

MZUAI和IIAI在NIPS2023上的一篇论文&#xff0c;用prompt来编码degradation&#xff0c;然后用来guide restoration network&#xff0c;使得模型能够泛化到不同degradation types and levels&#xff0c;也就是说是一个模型一次训练能够应对多种degradation的unified model。文…

讲座PPT分享|医学人工智能开始进入黄金时代|24年6月·讲座速递·06-03

小罗碎碎念 这期推文想分享的是自己四月底受邀做的一个报告——主题是“人工智能在肿瘤领域的进展&人工智能在脊柱外科领域中的进展”。 先解释一下&#xff0c;为什么我一个研究肿瘤的&#xff0c;会去关注脊柱外科——因为受到了脊柱外科医生的邀请&#xff0c;去给他们…

每日练习——牛客周赛 Round 45

小紫的总分 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行代码 #include<iostream> using namespace std; int main(){int a,b,c,d,e,sum;cin>>a>>b>>c>>d>>e;sumabcde;if(sum>100){ cout<<"YES";}else cout&…

家政预约小程序09小程序分享及海报分享

目录 1 设置弹窗2 制作海报总结 上一篇我们介绍了服务详情页面的开发&#xff0c;本篇介绍一下用户分享及海报分享的功能 1 设置弹窗 当用户点击分享按钮的时候&#xff0c;系统弹出弹窗界面&#xff0c;提供分享好友及分享海报的选项。选中页面组件&#xff0c;添加弹窗组件 …