当前位置: 首页 > news >正文

排序算法的实现(插入,希尔,选择,冒泡,堆排,快排)

目录

1.选择排序

2.冒泡排序

3.堆排序

4.插入排序

5.希尔排序

6.快排

6.1快排的优化

6.2快排(双指针法)

6.3快排(非递归)

7.归并排序

7.1归并非递归

8.计数排序


1.选择排序

对n个元素进行选择排序,我们可以遍历一轮找出最大值放在末尾,直到循环n-1次。

为了提高效率,我们可以同时找出最大值和最小值,分别放在末尾和开头。

//选择排序
void SelsectSort(int* a,int n)
{int begin=0,end=n-1;//begin要参与排序元素的第一个 end参与排序元素的最后一个 while(begin<end){int maxi=begin,mini=begin,i;//maxi记录最大值下标 mini记录最小值的下标 for(i=begin;i<=end;i++){if(a[maxi]<a[i]) maxi=i;if(a[mini]>a[i]) mini=i;}Swape(&a[maxi],&a[end]);//最大值放最后面 if(mini==end) mini=maxi;//如果最后面正好是最小值 那最小值会跑到下标为maxi上 Swape(&a[mini],&a[begin]);//最小值放最前面 begin++;//把已经排好的退出循环 end--;}
}

2.冒泡排序

左边和右边比较,大于就交换。每循环一趟最大值都会出现在最右边。

//冒泡排序
void BubbleSort(int* a,int n)
{int i,j;for(i=0;i<n-1;i++)//循环趟数 {for(j=0;j<n-1-i;j++)//-i减去排好的 {if(a[j]>a[j+1]) Swape(&a[j],&a[j+1]); }}
}

3.堆排序

要实现堆排序,我们先要用向下调整对数组建立堆结构。(向下调整比向上调整效率高)

实现升序就建大堆,堆顶为最大值,堆顶与最后一个元素交换,然后把最后一个元素(也就是最大值)剔除,再进行建堆。一直循环直到只剩堆顶元素。

同样降序就建小堆。

//向下调整(大堆) 根节点下标0
void AdjustDown(HPDataType*a,int n,int parent)//n为元素个数,最后一个元素下标为n-1 
{   int child=parent*2+1;//找当前父母孩子 while(child<n){if(child+1<n&&a[child]<a[child+1]) child++;//找最大的孩子 if(a[parent]<a[child])//大的值向上调 {change(&a[parent],&a[child]); }else break;//父母节点>=孩子节点 符合堆结构 不用继续向下调整parent=child;//继续向下进入下一层循环 child=parent*2+1;}
} 
// 对数组进行堆排序(升) 
void HeapSort(int* a, int n)
{   int i;for(i=(n-1-1)/2;i>=0;i--)//n-1最后一位元素下标 (n-1-1)/2找最后一位结点的父母下标 {                          AdjustDown(a,n,i);//向下交换 建堆 }int end=n-1;//end最后一个元素下标 while(end>0){change(&a[0],&a[end]);//最大元素与最后一个元素交换 AdjustDown(a,end,0);//向下交换找出最大值 时间复杂度logn (因为end传过去是被当作元素个数来看待,最后一个元素不会参与堆的再构建)end--;//最后一个元素排完,--脱离堆结构 }//循环再找次大 并排到堆结构的最后一位 
}

4.插入排序

对于第n个元素,我们先用tmp记录它的值,如果比前一个元素小,前一个元素就后移,直到大于等于前一个数,或者到0下标结束,最后在结束位置插入tmp。

插入排序的基本思路:
从第二个元素开始,将当前元素与前面已经排好序的部分进行比较。
找到合适的位置,将当前元素插入到该位置。
重复这个过程,直到整个序列有序。
插入排序的过程
1.以数组 [5, 2, 9, 1, 5, 6] 为例,插入排序的过程如下:

从第二个元素 2 开始,将其与前面的元素 5 比较。2 小于 5,所以交换它们。
2.数组变成 [2, 5, 9, 1, 5, 6]
处理第三个元素 9,9 大于 5,不需要交换。
3.数组仍然是 [2, 5, 9, 1, 5, 6]
处理第四个元素 1,将其与前面的元素逐一比较,直到找到合适的位置。1 小于所有的元素,所以将其放在最前面。
4.数组变成 [1, 2, 5, 9, 5, 6]
处理第五个元素 5,与前面的元素逐一比较,找到合适位置,将其插入到 [2, 5, 9] 和 6 之间。
5.数组变成 [1, 2, 5, 5, 9, 6]
处理第六个元素 6,将其插入到 9 和 5 之间。
6.数组变成 [1, 2, 5, 5, 6, 9]
最终,整个数组变成了 [1, 2, 5, 5, 6, 9],即排序完成。

// 插入排序
void InsertSort(int* a, int n)
{int i;for(i=0;i<n-1;i++)//排n个元素 循环n-1次 {int end=i;//0~end有从小到大的顺序 int tmp=a[end+1];//记录a[end+1]的值 while(end>=0){if(tmp<a[end])//比后面小就覆盖(本质还是互换) {a[end+1]=a[end]; end--;}else break;//比后面大就终止 }a[end+1]=tmp;//在终止位置上存入tmp }
}

5.希尔排序

希尔排序是插入排序变化来的,希尔排序可以分为预排序 细排。

预排序的目的是把无序的数组变成接近有序。我们可以把一组数组分为多组,在同一组中每个元素在原数组的下标之间的距离(gap)都是一样的,然后对每一组进行插入排序,使原数组接近有序。

细排通过插入排序(gap==1)把接近有序的数组变成有序。

//希尔排序 
void ShellSort(int* a, int n)
{int gap=n,i;while(gap>0){ gap/=2;//最终gap变1 for(i=0;i<n-gap;i++)//每组轮流排一次 {   int end=i; //end在一组内最后一个有序元素的下标 int tmp=a[end+gap];//tmp一组内最后一个有序元素的下一个元素 while(end>=0){if(tmp<a[end]){a[end+gap]=a[end];//比后面小就覆盖(本质还是互换) end-=gap;//比较下一个元素 }else break;//比后面大就终止}a[end+gap]=tmp;//在终止位置上存入tmp } }
}

时间复杂度大概为n^1.3。

6.快排

快排本质是利用二叉树递归的思想。

首先找一个值设为key(一般为首尾元素),假设我们以第一个元素为key,先从最后一个元素开始找比key小的值,找到就停下,然后再从第一个元素开始找比key大的元素,找到就和比key小的值交换,一直循环。(如果以最后一个元素为key,就先从第一个元素开始找)

直到两者相遇,相遇结点的值再和key交换。此时key左边的值都比它小,右边的值都比它大。

(如果相遇结点的值比key大还交换吗?结论:相遇结点的值永远小于等于key 原因在代码中)

我们可以把key结点看作根,它的左边看作左子树,右边看作右子树。左右子树分别递归循环,排好中间位置的元素,直到子树只有一个结点,或者为空。

//快速排序
void QuitSort(int *a,int begin,int end)//begin第一个元素 end最后一个元素下标 
{int ki=begin,bi=begin,ei=end;//ki记录key值的下标 便于后面交换 if(begin>=end) return;//子树为空或者只有一个结点,直接返回 while(begin<end){if(a[end]>a[ki]) end--;//key对面的下标先动(一般以起点/终点为key) 找比key小的值 if(a[begin]<a[ki]) begin++;//找比key大的值 Swape(&a[end],&a[begin]);} Swape(&a[begin],&a[ki]);//此时key左边的值都比key小,右边都比key大 QuitSort(a,bi,ki-1);//遍历左子树 对key左边的值进行排序 QuitSort(a,ki+1,ei);//遍历右子树 对key右边的值进行排序
}
//begin和end相遇结点的值一定不大于key(从小到大排)
//1.begin碰end 此时end是不动的 说明a[end]<key
//2.end碰begin 这又可以分为2种情况
//(1)end和begin相遇前至少进行过一次交换 交换完后end先动碰到begin 因为交换过a[begin]<key
//(2)end和begin相遇前没有进行过交换 end会一直--直到碰到begin  此时begin和end同时指向key 

6.1快排的优化

1.取key随机性高,容易取到极端值

对与这个问题,我们可以采用三目取中法来解决。在数组开头 结尾 中间 3个值中取一个中间值并作为key。

我们写一个在3个数中返回中间值下标的函数就可以了

​
//三目取中 
int GetMidi(int *a,int begin,int end)
{int midi=(begin+end)/2;if(a[midi]<a[begin]){if(a[end]<a[midi]) return midi;else if(a[begin]>a[end]) return end;//此时midi是最小值 返回较小的 else return begin;} else  //a[midi]>=a[begin]{if(a[end]>a[midi]) return midi;else if(a[end]>a[begin]) return end;//此时midi是最大值 返回较大的 else  return begin;}
}​

2.函数递归太多 栈内存空间消耗大

我们知道在满二叉树中最后一层结点个数大约占整个二叉树的%50,最后二层占%75。

而在快排中如果需要排序的个数太少,没有必要去建立栈来排,我们可以直接采用插入排序解决。

再加上三目取中法,我们就可以写出下面的函数。

//优化快排 
void ImproveQuitSort(int *a,int begin,int end)//begin第一个元素 end最后一个元素下标 
{   if(end-begin+1<10)//减少建栈(内存) 量少的直接用插入解决 {InsertSort(a,end-begin+1);return;}int ki=GetMidi(a,begin,end),bi=begin,ei=end;//三目取中ki取中间值的下标Swape(&a[begin],&a[ki]);//key与a[begin]交换 使key总位于起始位置 //if(begin>=end) return;//子树为空或者只有一个结点,直接返回 while(begin<end){if(a[end]>a[ki]) end--;//key对面的下标先动(一般以起点/终点为key) 找比key小的值 if(a[begin]<a[ki]) begin++;//找比key大的值 Swape(&a[end],&a[begin]);}Swape(&a[begin],&a[ki]);//此时key左边的值都比key小,右边都比key大 ImproveQuitSort(a,bi,ki-1);//遍历左子树 对key左边的值进行排序 ImproveQuitSort(a,ki+1,ei);//遍历右子树 对key右边的值进行排序
}

6.2快排(双指针法)

对于快排的实现,我们同样可以使用二个指针来解决。

1.取第一个元素为key,prve指向下标为0的元素,cur指向prve的前一个。

2.如果cur指向的值大于key cur就++,否则prve先++,再和cur交换,最后cur++。

3.当cur指向最后一个元素后面时,prve和key交换。

4.递归循环。

这个过程本质上就是不断的把大于key的值往后排,小于key的向前移。

(prve永远不会超过cur,因为无论cur大于还是小于key都会++)

//快排双指针法
void  PointerQuitSort(int *a,int begin,int end)
{if(begin>=end) return;int keyi=begin;//第一个元素为key int prev=begin;//prve指向begin int cur=prev+1;//cur在prve前面 while(cur<=end)//cur到最后一个元素后面结束 {if(a[cur]>a[keyi]) cur++;//如果cur指向的元素大于key就++ 小于key就停下 else Swape(&a[++prev],&a[cur++]);//否则prve先++ 再与cur指向元素交换 最后cur++ (先++是为了让prve指向大于key的值) }Swape(&a[prev],&a[keyi]);//当cur越界时 prev指向的值仍是小于key的 可以直接与key交换 keyi=prev;PointerQuitSort(a,begin,keyi-1);PointerQuitSort(a,keyi+1,end);
}

6.3快排(非递归)

我们可以利用栈结构来模拟递归过程。

我们可以把函数参数也就是begin,end压入栈,当一对begin,end处理完,再压入它右左子树的begin,end直到栈为空。因为栈是先进后出,如果想先处理左子树就先压入右子树,再压入左子树。

(注意入栈 出栈顺序,不要把左右范围搞反)

(压入左右子树范围时 注意不要越界)

//快排非递归
void StackQuitSort(int *a,int begin,int end)
{ST q;StackInit(&q);StackPush(&q,end);//先压右边 StackPush(&q,begin);//再压左边 while(!StackEmpty(&q)){int left=StackTop(&q);//此时栈顶元素为begin StackPop(&q);int right=StackTop(&q);StackPop(&q);if(left>=right) return;//用双指针进行一趟排序 int keyi=left;int prev=left;int cur=prev+1;while(cur<=right){if(a[cur]>a[keyi]) cur++;else Swape(&a[++prev],&a[cur++]); }Swape(&a[prev],&a[keyi]);keyi=prev;if(keyi+1<=right)//防止keyi+1越界 先压右右子树  {StackPush(&q,right);StackPush(&q,keyi+1);}if(keyi-1>=left)//再压左子树 (出栈时会先遍历左子树) {StackPush(&q,keyi-1);StackPush(&q,left);}}StackDestroy(&q);
}

7.归并排序

归并排序递归实现过程就像二叉树的后续遍历。

1.从中间不断分左右子树 直到剩1个结点时返回。

2.然后归并左右子树 较小的值存入tmp中,完成后把tmp复制到a中。

3.一级一级向上返回。

//归并排序
void _MergeSort(int *a,int begin,int end,int* tmp)
{if(begin==end) return;//只有一个不用排 int mid=(begin+end)/2;int i=begin;//记录起始位置 int begin1=begin,end1=mid;//左子树范围 int begin2=mid+1,end2=end; //右子树范围 _MergeSort(a,begin1,end1,tmp);_MergeSort(a,begin2,end2,tmp);while(begin1<=end1&&begin2<=end2)//左右子树中选取最小值存入 {if(a[begin1]>a[begin2]){tmp[i++]=a[begin1];begin1++;}else{tmp[i++]=a[begin2];begin2++;		}}while(begin1<=end1) tmp[i++]=a[begin1++];//将剩余元素按顺序存入数组 while(begin2<=end2) tmp[i++]=a[begin2++];memcpy(a+begin,tmp+begin,(end - begin + 1)*4);//将tmp排好数据复制到a 最后一个参数是字节数
} void MergeSort(int *a,int n)
{int *tmp=(int*)malloc(sizeof(int)*n);//给新建数组分配空间 if(tmp==NULL){perror("malloc fail");return ; }_MergeSort(a,0,n-1,tmp);//防止反复申请空间 再建一个函数进行递归free(tmp);tmp=NULL;return;
} 

7.1归并非递归

递归变非递归我们可以利用栈,队列或者直接用while循环来解决。

归并非递归直接从叶子结点(gap==1)开始,两个两个进行个归并。(gap为一组中的元素个数)

最后一层叶子结点归并完,进入下一层接着归并。

以此循环 直到一组中的元素大于整个数组的元素个数(gap>n)

//归并排序(非递归)
void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);//给新建数组分配空间 if (tmp == NULL){perror("malloc fail");return;}int gap = 1;//gap为一组中要排序的个数(可以理解为子树中结点个数)int i,j;while (gap < n)//一组中的个数要小于等于n 两组两组就行归并{for (i = 0; i < n; i += 2*gap)//i为初始位置 因为两两进行归并 所以i+=2*gap{j = i;//j记录初始位置int begin1 = i, end1 = begin1 + gap - 1;//两组元素归并,第一组的左右范围int begin2 = end1 + 1, end2 = begin2 + gap - 1;//第二组的左右范围if (end1 >= n || begin2 >= n) break;//没有第二组元素 不用归并if (end2 >= n) end2 = n - 1;//第二组元素有一部分 归并 要防止越界while (begin1 <= end1 && begin2 <= end2)//两组元素进行归并{if (a[begin1] > a[begin2]){tmp[j++] = a[begin1];begin1++;}else{tmp[j++] = a[begin2];begin2++;}}while (begin1 <= end1) tmp[j++] = a[begin1++];while (begin2 <= end2) tmp[j++] = a[begin2++];memcpy(a + i, tmp + i, (end2-i + 1) * sizeof(int));//i初始位置 end2终止位置}gap *= 2;//进入下一层 两组元素归并成一个所以*2}//本质上就是从叶子结点开始不断归并free(tmp);tmp = NULL;return;
}

实现代码时要注意1.左右子树范围不能越界

2.利用tmp对两组元素进行归并时,要用 j 先记录起始位置 i 后续j++不断存入下一个

8.计数排序

计数排序是对一组范围集中的数据进行排序,按顺序统计数组中相同元素出现的次数,同一个元素出现几次就输出几次。

1.首先我们要开辟一组数组tmp来记录数组中相同元素出现的次数,开辟数组的大小就要根据原数组值的范围来定,我们求出原数组中的max min就可以得出范围。

2.然后我们通过遍历的方式来出原数组中相同元素出现的次数。

3.最后根据tmp数组中记录的次数,有几次就在原数组中存入几次。

//计数排序
void CountSort(int *a,int n)
{int i,j=0,min=a[0],max=a[0];for(i=0;i<n;i++)//找出最大最小值 {if(min>a[i]) min=a[i];if(max<a[i]) max=a[i];}int range=max-min+1;//范围 int*tmp=(int*)malloc(sizeof(int)*range);if (tmp == NULL){perror("malloc fail");return;}memset(tmp,0,sizeof(int)*range);//初始化为0 for(i=0;i<n;i++)//记录不同数值出现几次 {tmp[a[i]-min]++;//因为不一定从0开始,所以要减去min }for(i=0;i<range;i++)//同一个值出现几次就输出几次 {while(tmp[i]){a[j++]=i+min; tmp[i]--;}}
} 

相关文章:

排序算法的实现(插入,希尔,选择,冒泡,堆排,快排)

目录 1.选择排序 2.冒泡排序 3.堆排序 4.插入排序 5.希尔排序 6.快排 6.1快排的优化 6.2快排&#xff08;双指针法&#xff09; 6.3快排&#xff08;非递归&#xff09; 7.归并排序 7.1归并非递归 8.计数排序 1.选择排序 对n个元素进行选择排序&#xff0c;我们可以…...

【微服务】5、服务保护 Sentinel

Sentinel学习内容概述 Sentinel简介与结构 Sentinel是Spring Cloud Alibaba的组件&#xff0c;由阿里巴巴开源&#xff0c;用于服务流量控制和保护。其内部核心库&#xff08;客户端&#xff09;包含限流、熔断等功能&#xff0c;微服务引入该库后只需配置规则。规则配置方式有…...

C 语言函数指针 (Pointers to Functions, Function Pointers)

C 语言函数指针 {Pointers to Functions, Function Pointers} 1. Pointers to Functions (函数指针)2. Function Pointers (函数指针)2.1. Declaring Function Pointers2.2. Assigning Function Pointers2.3. Calling Function Pointers 3. Jump Tables (转移表)References 1. …...

Mesa llvmpipe和softpipe对比

Mesa 后端性能分析&#xff1a;LLVM vs Software Pipe 当调试没有显卡的时候&#xff0c;可以使用cpu软件模拟的mesa-3d&#xff0c;后端采用kms_swrast_dri.so&#xff0c;发现管线使用llvmpipe的速度明显优于softpipe&#xff1b; 背景介绍 Mesa 是一个开源的图形库&#xf…...

【Spiffo】排障:VsCode报错“过程试图写入的管道不存在”(网络环境正常且地址正常的情况下依然出现)

摘要&#xff1a; VsCode使用remote-ssh报错nstall terminal quit with output: 过程试图写入的管道不存在&#xff0c;且输出类似下图的信息 一般来说这种情况更可能是网络环境出了问题&#xff0c;那连不上自不必多说&#xff0c;这里想讨论一种特殊情况。 有一种可能性&…...

Python图形界面(GUI)Tkinter笔记(二十一):Messagebox信息提示功能控件

messagebox 就像是 tkinter 库里的一个好帮手,它能帮你弹出各种各样的消息框给用户看。这些消息框可以告诉用户很多东西,比如提示、警告或者错误信息之类的。在 tkinter 库里,messagebox 这个模块有很多不同的函数,每个函数都能弹出一种特定的消息框。用这些函数,开发者可…...

KUKA机器人如何修改程序并下载到机器人控制器中?

KUKA机器人如何修改程序并下载到机器人控制器中? 如下图所示,首先将使用的网卡的IP地址设置为自动获得, 打开workvisual软件,点击搜索,正常情况下可以搜索到项目文件,选中后双击进入, 如下图所示,此时,workvisual会自动从机器人控制器中下载项目文件到电脑上,耐心等待…...

jmeter 中 BeanShell 预处理程序、JSR223后置处理程序使用示例

1. 各个组件如何新建的&#xff1f; 2. "http请求" 组件内容样例&#xff1a; "消息体数据" 源码&#xff1a; {"task_tag": "face_detect","image_type": "base64","extra_args": [{"model"…...

「Mac畅玩鸿蒙与硬件53」UI互动应用篇30 - 打卡提醒小应用

本篇教程将实现一个打卡提醒小应用&#xff0c;通过用户输入时间进行提醒设置&#xff0c;并展示实时提醒状态&#xff0c;实现提醒设置和取消等功能。 关键词 打卡提醒状态管理定时任务输入校验UI交互 一、功能说明 打卡提醒小应用包含以下功能&#xff1a; 提醒时间输入与…...

前端开发【插件】moment 基本使用详解【日期】

moment.js 是一个非常流行的 JavaScript 库&#xff0c;用于处理和操作日期与时间。它提供了丰富的 API 来处理各种日期、时间和格式化的操作。尽管随着 Date API 的增强&#xff0c;moment.js 被视为“过时”&#xff0c;并且推荐使用 date-fns 或 luxon 等库来替代&#xff0…...

Apache Celeborn 在B站的生产实践

背景介绍 Shuffle 演进 随着B站业务的飞速发展,数据规模呈指数级增长,计算集群也逐步从单机房扩展到多机房部署模式。多个业务线依托大数据平台驱动核心业务,大数据系统的高效性与稳定性成为公司业务发展的重要基石。如图1,目前在大数据基础架构下,我们主要采用 Spark、Fl…...

imageio 图片转mp4 保存mp4

目录 安装&#xff1a; imageio 图片转mp4 numpy 保存mp4 安装&#xff1a; FFMPEG: pip install imageio[ffmpeg] pyav: pip install imageio[pyav] imageio 图片转mp4 import glob import osimport cv2 import imageio from natsort import natsortedfrom PIL import …...

【C语言程序设计——选择结构程序设计】求阶跃函数的值(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 1. 选择结构基本概念 2. 主要语句类型​&#xff08;if、if-else、switch&#xff09; 3. 跃迁函数中变量的取值范围 4. 计算阶跃函数的值 编程要求 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;输入x的值&#x…...

基于 Solana Playground (pg模式)发行自定义参数的代币

文章目录 要做的事1、水龙头&#xff08;devnet 环境&#xff09;2、Solana Playground2.1、选择环境 3、基于 Solana Playground &#xff08;pg模式&#xff09;发行自定义参数的代币3.1、账户体系3.2、代码 4、浏览器& Phantom钱包 展示代币图片4.1、 浏览器和钱包展示的…...

代码随想录算法训练营第七十天 | 拓扑排序精讲,Dijkstra(朴素版)精讲,Dijkstra(堆优化版)精讲

拓扑排序精讲 题目讲解&#xff1a;代码随想录 重点&#xff1a; 给出一个有向图&#xff0c;把这个有向图转成线性的排序就叫拓扑排序。拓扑排序也是图论中判断有向无环图的常用方法。拓扑排序的过程&#xff0c;其实就两步&#xff1a; 找到入度为0的节点&#xff0c;加入结…...

基于 Python Django 的西西家居全屋定制系统(源码+部署+文档)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

excel填充十六进制

excel填充十六进制 A10x000020x000130x000240x000350x000460x000570x000680x000790x0008100x0009110x000A120x000B130x000C140x000D150x000E160x000F 在A1表格中&#xff0c;输入&#xff1a;“0x”&DEC2HEX(ROW()-1,4) 然后进行下拉即可生成如表格显示十六进制...

scrapy 教程

Scrapy Tutorial In this tutorial, we’ll assume that Scrapy is already installed on your system. If that’s not the case, see Installation guide. We are going to scrape quotes.toscrape.com, a website that lists quotes from famous authors. This tutorial …...

IDE和IDEA详解和具体差异

1. IDE(集成开发环境)概述 1.1 什么是 IDE? IDE(Integrated Development Environment,集成开发环境)是一种为开发者提供全面编程工具的软件应用程序。它将代码编辑、编译、调试、版本控制等功能集成在一个统一的界面中,旨在提高开发效率,减少开发者在不同工具之间切换…...

使用MPTCP+BBR进行数据传输,让网络又快又稳

1.前言 在前文《链路聚合技术——多路径传输Multipath TCP(MPTCP)快速实践》中我们使用mptcpize run命令实现了两个节点间通信使用MPTCP协议进行传输&#xff0c;并实现了传输速率的聚合。 实际应用中更推荐原生支持mptcp的应用&#xff0c;在MPTCP官网中可以看到如TCPDump、…...

【网络】网络基础知识(协议、mac、ip、套接字)

文章目录 1. 计算机网络的背景2. 认识网络协议2.1 协议分层2.2 OS与网络的关系 3. 网络传输基本流程3.1 局域网通信流程3.2 跨网络通信流程 4. Socket 编程预备4.1 理解源IP地址和目的IP地址4.2 端口号与Socket4.3传输层的典型代表4.4 网络字节序 5. socket 编程接口5.1 介绍5.…...

Unity【Colliders碰撞器】和【Rigibody刚体】的应用——小球反弹效果

目录 Collider 2D 定义&#xff1a; 类型&#xff1a; Rigidbody 2D 定义&#xff1a; 属性和行为&#xff1a; 运动控制&#xff1a; 碰撞检测&#xff1a; 结合使用 实用检测 延伸拓展 1、在Unity中优化Collider 2D和Rigidbody 2D的性能 2、Unity中Collider 2D…...

游戏引擎学习第75天

仓库:https://gitee.com/mrxiao_com/2d_game_2 Blackboard: 处理楼梯通行 为了实现楼梯的平滑过渡和角色的移动控制&#xff0c;需要对楼梯区域的碰撞与玩家的运动方式进行优化。具体的处理方式和遇到的问题如下&#xff1a; 楼梯区域的过渡&#xff1a; 在三维空间中&#x…...

ModelScope ms-swift:轻量级模型微调框架

ModelScope ms-swift&#xff1a;轻量级模型微调框架 介绍支持的模型支持的技术使用方法为什么选择ms-swift&#xff1f;结论 介绍 ModelScope ms-swift是ModelScope社区提供的一个官方框架&#xff0c;用于大型语言模型&#xff08;LLMs&#xff09;和多模态大型模型&#xf…...

管理加密SQLite数据库的软件工具研究

使用软件工具管理加密的 SQLite 数据库是一个常见需求&#xff0c;尤其是当需要保护敏感数据时。以下是实现此目标的步骤和相关工具推荐&#xff1a; 1. 选择支持加密的 SQLite 版本 SQLite 默认并不支持加密功能。你需要使用以下方法之一来启用加密&#xff1a; SQLite Encry…...

react 封装一个类函数使用方法

1.编写ProductCount函数 class ProductCount {public static getProductCount(count: number): string {if (count < 10) {return 当前数量: 0${count};}return 当前数量: ${count};} }export default ProductCount;2.在代码文件中导入 ProductCount 类。 import ProductC…...

Windows 11 上通过 WSL (Windows Subsystem for Linux) 安装 MySQL 8

在 Windows 11 上通过 WSL (Windows Subsystem for Linux) 安装 MySQL 8 的步骤如下&#xff1a; ✅ 1. 检查 WSL 的安装 首先确保已经安装并启用了 WSL 2。 &#x1f527; 检查 WSL 版本 打开 PowerShell&#xff0c;执行以下命令&#xff1a; wsl --list --verbose确保 W…...

解决 IntelliJ IDEA 中 Tomcat 日志乱码问题的详细指南

目录 前言1. 分析问题原因2. 解决方案 2.1 修改 IntelliJ IDEA 的 JVM 选项2.2 配置 Tomcat 实例的 VM 选项 2.2.1 设置 Tomcat 的 VM 选项2.2.2 添加环境变量 3. 进一步优化 3.1 修改 Tomcat 的 logging.properties3.2 修改操作系统默认编码 3.2.1 Windows 系统3.2.2 Linux …...

jenkins入门4 --window执行execute shell

1、启动关闭jenkins 在Windows环境下&#xff0c;如果你需要关闭Jenkins服务&#xff0c;可以通过以下几种方式&#xff1a; 1、使用Windows服务管理器&#xff1a; 打开“运行”对话框&#xff08;Win R&#xff09;&#xff0c;输入services.msc&#xff0c;然后回车。 在服…...

51c嵌入式~单片机~合集4

我自己的原文哦~ https://blog.51cto.com/whaosoft/12868932 一、时钟失效之后&#xff0c;STM32还能运行&#xff1f; 问题&#xff1a; 该问题由某客户提出&#xff0c;发生在 STM32F103VDT6 器件上。据其工程师讲述&#xff1a;在其产品的设计中&#xff0c;STM32 的 H…...

OKHttp调用第三方接口,响应转string报错okhttp3.internal.http.RealResponseBody@4a3d0218

原因分析 通过OkHttp请求网络&#xff0c;结果请求下来的数据一直无法解析并且报错&#xff0c;因解析时String res response.body().toString() 将toString改为string即可&#xff01;...

杰发科技——使用ATCLinkTool解除读保护

0. 原因 在jlink供电电压不稳定的情况下&#xff0c;概率性出现读保护问题&#xff0c;量产时候可以通过离线烧录工具避免。代码中开了读保护&#xff0c;但是没有通过can/uart/lin/gpio控制等方式进行关闭&#xff0c;导致无法关闭读保护。杰发所有芯片都可以用本方式解除读保…...

SQL 幂运算 — POW() and POWER()函数用法详解

POW() and POWER()函数用法详解 POW() 和 POWER() —计算幂运算&#xff08;即一个数的指定次方&#xff09;的函数。 这两个函数是等价的&#xff0c;功能完全相同&#xff0c;只是名字不同。 POW(base, exponent); POWER(base, exponent); base&#xff1a;底数。exponen…...

【Shell脚本】Docker构建Java项目,并自动停止原镜像容器,发布新版本

本文简述 经常使用docker部署SpringBoot 项目&#xff0c;因为自己的服务器小且项目简单&#xff0c;因此没有使用自动化部署。每次将jar包传到服务器后&#xff0c;需要手动构建&#xff0c;然后停止原有容器&#xff0c;并使用新的镜像启动&#xff0c;介于AI时代越来越懒的…...

【ArcGIS Pro二次开发实例教程】(2):BSM字段赋值

一、简介 一般的数据库要素或表格都有一个BSM字段&#xff0c;用来标识唯一值。 此工具要实现的功能是&#xff1a;按一定的规律&#xff08;前缀中间的填充数字OBJECT码&#xff09;来给BSM赋值。 主要技术要点包括&#xff1a; 1、ProWindow的创建&#xff0c;Label,Comb…...

VSCode函数调用关系图插件开发(d3-graphviz)

文章目录 1、如何在VSCode插件webview中用d3-graphviz绘图2、VSCode插件使用离线d3.min.js、d3-graphviz3、使用 `@hpcc-js/wasm` 包在 Node.js 环境直接转换dot为svg1、如何在VSCode插件webview中用d3-graphviz绘图 我来帮你创建一个 VS Code 插件示例,实现右键菜单触发 Web…...

OCR图片中文字识别(Tess4j)

文章目录 Tess4J下载 tessdataJava 使用Tess4j 的 demo Tess4J Tess4J 是 Tesseract OCR 引擎的 Java 封装库&#xff0c;它让 Java 项目更轻松地实现 OCR&#xff08;光学字符识别&#xff09;功能。 下载 tessdata 下载地址&#xff1a;https://github.com/tesseract-ocr/…...

leetcode 面试经典 150 题:同构字符串

链接同构字符串题序号205题型字符串解法哈希表难度简单熟练度✅✅✅✅ 题目 给定两个字符串 s 和 t &#xff0c;判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t &#xff0c;那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符&#…...

算法-泰波那契

力扣题目链接&#xff1a;1137. 第 N 个泰波那契数 - 力扣&#xff08;LeetCode&#xff09; 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 示例 1&…...

Mac修改文件权限

查看文件权限 ll -all 修改读写权限 sudo chmod -R arwx /usr/local/mysql-5.7.30-macos10.14-x86_64/data/a_test 修改用户分组 sudo chown -R _mysql:wheel /usr/local/mysql-5.7.30-macos10.14-x86_64/data/b_test...

如何安装和配置PHP开发环境?

要安装和配置PHP开发环境&#xff0c;可以按照以下步骤进行&#xff1a; 一、下载和安装PHP 1&#xff1a;下载PHP&#xff1a; 访问PHP官方网站&#xff08;PHP: Downloads&#xff09;&#xff0c;选择适合您操作系统的版本进行下载。 2&#xff1a;解压并安装PHP&#x…...

深入探讨 Android 中的 AlarmManager:定时任务调度及优化实践

引言 在 Android 开发中&#xff0c;AlarmManager 是一个非常重要的系统服务&#xff0c;用于设置定时任务或者周期性任务。无论是设置一个闹钟&#xff0c;还是定时进行数据同步&#xff0c;AlarmManager 都是不可或缺的工具之一。然而&#xff0c;随着 Android 系统的不断演…...

【Vim Masterclass 笔记07】S05L19:Vim 剪切、复制、粘贴操作同步练习

文章目录 S05L19 Vim 剪切、复制、粘贴操作同步练习&#xff08;Exercise 05 - Cut, Copy and Paste&#xff09;1 训练目标2 操作指令2.1 打开 dyp.txt 文件2.2 交换文件的头两行2.3 将文件首行 put 到文件其他为止2.4 练习在光标位置的上方粘贴文本行2.5 通过交换字符顺序更正…...

【前端下拉框】获取国家国旗

一、先看效果 二、代码实现&#xff08;含国旗&#xff09; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…...

Elasticsearch 操作文档对数据的增删改查操作 索引库文档 操作数据 CRUD

介绍 在 Elasticsearch 中&#xff0c;文档的增、删、改、查操作是核心的基本功能。Elasticsearch 使用 RESTful API 提供这些操作&#xff0c;通常通过 HTTP 请求与 Elasticsearch 集群进行交互。 索引库 {"mappings": {"properties": {"title&qu…...

【动手学电机驱动】STM32-MBD(2)将 Simulink 模型部署到 STM32G431 开发板

STM32-MBD&#xff08;1&#xff09;安装 STM32 硬件支持包 STM32-MBD&#xff08;2&#xff09;Simulink 模型部署入门 STM32-MBD&#xff08;3&#xff09;Simulink 状态机模型部署 【动手学电机驱动】STM32-MBD&#xff08;2&#xff09;Simulink 模型部署入门 1. 软硬件条件…...

小试牛刀-SpringBoot集成SOL链

目录 一、什么是solanaj? 二、Pom依赖 三、主要类 3.1 RpcClient 3.2 PublicKey 3.3 Transaction 3.4 TransactionInstruction 四、示例代码 Welcome to Code Blocks blog 本篇文章主要介绍了 [小试牛刀-SpringBoot集成SOL链] ❤博主广交技术好友&#xff0c;喜欢文章的…...

数据结构大作业——家谱管理系统(超详细!完整代码!)

目录 设计思路&#xff1a; 一、项目背景 二、功能分析 查询功能流程图&#xff1a; 管理功能流程图&#xff1a; 三、设计 四、实现 代码实现&#xff1a; 头文件 结构体 函数声明及定义 创建家谱树头结点 绘制家谱树&#xff08;打印&#xff09; 建立右兄弟…...

【计算机网络】课程 实验二 交换机基本配置和VLAN 间路由实现

实验二 交换机基本配置和VLAN 间路由实现 一、实验目的 1&#xff0e;了解交换机的管理方式。 2&#xff0e;掌握通过Console接口对交换机进行配置的方法。 3&#xff0e;掌握交换机命令行各种模式的区别&#xff0c;能够使用各种帮助信息以及命令进行基本的配置。 4&…...

最新MySQL面试题(2025超详细版)

2025最新超详细MySQL面试题 文章目录 2025最新超详细MySQL面试题[toc]一、 SQL 和基本操作1. SQL的执行顺序2. 如何优化MySQL查询3. 常用的聚合函数4. 数据库事务5. 事务的四大特性(ACID)6. 视图7. MySQL中使用LIMIT子句进行分页8. MySQL中使用变量和用户定义的函数9. MySQL中的…...