八大排序算法细讲
目录
排序
概念
运用
常见排序算法
插入排序
直接插入排序
思想:
步骤(排升序):
代码部分:
时间复杂度:
希尔排序
思路
步骤
gap的取法
代码部分:
时间复杂度:
选择排序
直接选择排序
排升序思路:
排升序步骤:
代码部分:
时间复杂度:
堆排序
代码部分:
交换排序
冒泡排序
代码部分:
快速排序(递归版本)
思路:
hoare版本
排升序步骤:
相遇问题:
代码部分:
挖坑法版本
排升序思路:
代码部分:
前后指针版本:
排升序思路:
代码部分:
时间复杂度:
快速排序(非递归版本)
思路:
注意:
编辑
代码部分(找基准值部分用的是前后指针方法):
归并排序
思路:
排升序步骤:
代码部分:
时间复杂度:
非比较排序
计数排序
思路:
代码部分:
时间复杂度:
排序算法复杂度及稳定性分析
排序
概念
排序就是将一段记录,按照其中的某个或某些关键字大小,实现递增或递减的操作
运用
排序在我们的生活中运用也是极其广泛的,如:在购物软件中,根据不同条件来筛选商品;大学院校的排名……等等
常见排序算法
插入排序
直接插入排序
思想:
把待排序的记录按其关键码值的大小逐个插入到⼀个已经排好序的有序序列中,直到所有的记录插入完为止,得到⼀个新的有序序列
这种排序算法类似于玩扑克牌,就是依次将手中的牌进行排序
步骤(排升序):
1、先取出第二张牌与第一张进行比较,小的放前面,大的放后面
2、让后面的牌再进行上面那一步
这样看起来会比较抽象,举一个例子来实现就容易理解了
代码部分:
void InsertSort(int* arr, int n)
{for (int i = 0; i < n - 1; ++i){int end = i;int temp = arr[end + 1];while (end >= 0){if (arr[end] > temp){arr[end + 1] = arr[end];end--;}else{break;}}arr[end + 1] = temp;}
}
时间复杂度:
直接插入排序的时间复杂度为O(N^2),但在一般情况下是不会达到N^2的,只有在排序数组与要求排序方向相反时(也就是逆序),才会达到O(N^2)
这也就导致了一个问题,在面对逆序情况下,使用该排序算法,效率就会大大降低
面对这种情况,前人就在直接插入排序算法的基础上进行了改良,也就是接下来要讲的——希尔排序
希尔排序
根据上面的直接插入排序算法我们可以知道,在面对逆序数组时,算法复杂度太大了(O(N^2)),
所以前人就在该算法基础上进行了改良
思路
先选定一个整数,命名为gap,通常是gap=n/3+1,将带排序数组中元素根据gap值分为多组,也就是将相距gap值的元素分在同一组中,然后对每一组的元素进行排序,这是就完成一次排序,然后gap=gap/3+1,,再将数组根据gap值分为多组,进行插入排序,当gap=1时,就相当于进行直接插入排序算法。
步骤
步骤一(当gap>1):
1、将数组根据gap分为多组
2、将相距gap值的元素进行比较
注:步骤一也可以称为预排序,目的是为了:将数组转变为一个相对有序的情况,避免直接插入排序在面对逆序数组情况时时间复杂度变大
排升序时:小的元素在前面,大的元素在后面
排降序时:大的元素在前面,小的元素在后面
步骤二(当gap=1):
就相当于进行直接插入排序
举例可知
gap的取法
gap值的最初值取该数组的长度,当它进入while循环时,就先进行gap=gap/+1
然而,为什么是对gap/3,而不是除以其他值呢?
如果gap除以的值过小的话,比如:gap=gap/2,就会导致分的组太少,而每组内元素比较次数过多,while循环次数也会增多(因为gap值要不断除以2,直到gap=1时停止while循环)
如果gap除以的值过大的话,比如:gap=gap/8,就会导致分的组过多,而每组内元素比较次数较少,while循环次数少
所以gap除以的值要取适中的值,3则是较好的值
那为何还要加一呢?
加一的目的是为防止gap整除的值为0,这样可以防止gap=0时,直接退出循环,没有排序完全
代码部分:
void ShellSort(int* arr, int n)
{int gap = n;while (gap > 1)//gap不能等于1,如果为一进入循环,在gap/3+1中就会一直为1,就会死循环{gap = gap / 3 + 1;for (int i = 0; i < n - gap; ++i){int end = i;int temp = arr[end + gap];while (end >= 0){if (arr[end] > temp){arr[end + gap] = arr[end];end -= gap;}else{break;}}arr[end + gap] = temp;}}}
时间复杂度:
希尔排序算法的时间复杂度不好计算,大概为O(N^1.3)
选择排序
直接选择排序
排升序思路:
每一次循环,先从待排数组中找出最大和最小值,将最小值与待排数组的起始位置交换,最大值与待排数组的最后一个元素交换,直到所有待排数组元素排完
排升序步骤:
1、设立起始位置和最后一元素下标位置:begin、end,然后找到最大值和最小值下标
2、将最小值和起始元素交换、最大值和末尾元素交换
3、交换后,begin++、end--,然后进行[begin,end]区间元素的排序,按照上面两步
4、直到begin>end时结束排序
注:当begin与maxi、end与mini重叠时,会造成重复交换,所以就需要将maini和mini进行交换
代码部分:
void SelectSort(int* arr, int n)
{int begin = 0, end = n - 1;while (begin < end){int mini , maxi;mini = maxi = begin;for (int i = begin + 1; i <= end; ++i){if (arr[i] > arr[maxi]){maxi = i;}if (arr[i] < arr[mini]){mini = i;}}if (begin == maxi){maxi = mini;}Swap(&arr[begin], &arr[mini]);Swap(&arr[end], &arr[maxi]);begin++;end--;}
}
时间复杂度:
直接选择排序的时间复杂度很好理解,为O(N^2),因为它的效率不是很好,所以实际上很少会用到
堆排序
堆排序的讲解,在前面的文章已经讲解过了,就不在这里过多说明,有兴趣的朋友可以移步
二叉树:堆的建立和应用_二叉树的应用,两种创建方式-CSDN博客
代码部分:
void AdJustDown(int* arr, int parent, int n)//向下调整
{int child = parent * 2 + 1;while (child < n){//这里左右孩子的比较,c>c+1,交换建小堆;c<c+1,交换建大堆//建大堆,先找大孩子;建小堆,先找小孩子if (child + 1 < n && arr[child] < arr[child + 1]){child++;}//>建大堆//<建小堆if (arr[child] > arr[parent]){Swap(&arr[child], &arr[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
void HeapSort(int* arr, int n)//向下调整算法建堆:时间复杂度O(n)
{//排升序建大堆//排降序建小堆//先建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdJustDown(arr, i, n);}//再排序int end = n - 1;while (end > 0){Swap(&arr[0], &arr[end]);//交换堆顶和尾结点AdJustDown(arr, 0, end);end--;}}
交换排序
冒泡排序
冒泡排序大家应该都不陌生,是我们C语言学习的第一个排序算法,它的时间复杂度为O(N^2),
关于它的思路步骤我就不过多说明了,它在实际当中也基本不会用到,它是起着一种教学作用的排序算法
代码部分:
void BubbleSort(int* arr, int n)
{int i = 0;for (i = 0; i < n - 1; ++i){int j = 0;int flag = 1;for (j = 0; j < n - 1 - i; ++j){if (arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;flag = 0;}}if (flag == 1)//当提前完成排序后,就直接退出循环{break;}}
}
快速排序(递归版本)
快速排序可以说是排序算法中最重要的排序算法,在实际学习和工作中运用得最多,接下来我们来好好学习快速排序算法
思路:
任取待排数组中某一个元素作为基准值(key),然后将基准值放到正确位置上,按照基准值将数组分割成两个序列,左子序列中所有元素小于基准值,右子序列中所有元素大于基准值(这里排升序),然后再对左右子序列重复该过程,直到所有元素都排列再在相对应位置上为止
hoare版本
排升序步骤:
1、找基准值:
起始令首元素为基准值(key),设right和left,right为末尾元素下标,left为首元素下标,
让left从左往右找比基准值大的值,right从右往左找比基准值大的值,
找到以后将left与right指向的值进行交换,这个交换的前提是right>=left;
而当right小于left时right所指向的值就与key进行交换,这时key就回到了正确的位置
2、二分
根据key所在位置,对数组进行二分,将数组分为左右两个子序列,然后再对左右两个子序列进行上述操作
相遇问题:
1、相遇点值小于基准值
由此可知,当相遇点小于基准值时,left依旧减减
2、相遇点值大于基准值
由此可知,当相遇点大于基准值时,right依旧加加
3、当相遇点值等于基准值
这种情况看似两种都可以,但是当选择了right依旧减减时,就会导致面对下面这种情况时,时间复杂度大大提高
这种情况便是相遇点值与基准值相同的情况,在这种情况下,该排序算法的时间复杂度就会大大提高,无法进行高效的分割排序
其实这也是这种hoare版本快速排序在面对待排数组中重复元素过多情况下的弊端
代码部分:
int Hoare_QuickSort(int* arr, int left, int right)
{int keyi = left;left++;while (left <= right){//rigth从右往左找比基准值小的值while (left<=right && arr[right]>arr[keyi])//这里的arr[rigth]>arr[keyi]只能取大于号,不能加上等于号,//加上的话在面对数组全相等或有序数组时,时间复杂度会变大{right--;}//left从左往右找比基准值大的值while (left<=right && arr[left]<arr[keyi])//这里的情况和rigth是一样的{left++;}if (left <= right)//当left还未大于rigth时,就进行交换{Swap(&arr[left], &arr[right]);}}Swap(&arr[right], &arr[keyi]);keyi = right;return keyi;
}void QuickSort(int* arr, int left, int right)//排升序
{if (left >= right){return;}//找基准值int keyi = Hoare_QuickSort(arr, left, right);//二分//[left,keyi-1] keyi [keyi+1,right]QuickSort(arr, left, keyi - 1);QuickSort(arr, keyi + 1, right);}
挖坑法版本
排升序思路:
设立左右指针:left、right,先将基准值视为第一个坑:hole,
right从右往左找比基准值小的数,找到以后就放入到hole的位置,然后righ处就为新的坑;
left从左往右找比基准值大的数,找到以后就放入到hole的位置,然后left处就为新的坑;
当right==left时,就将保存的基准值放入到两者相遇处
就这样便完成了第一次基准值的寻找
找到以后就和hoare版本一样进行二分
注:
这种方法起始的left只能指向首元素;
和hoare版本不同的是,当right从右往左找比基准值小的值时,当遇到比基准值大的或者等于的值时,继续往左找;left也是一样的
代码部分:
int Hole_QuickSort(int* arr, int left, int right)
{int hole = left;int key = arr[hole];while (left < right){while (left<right && arr[right]>=key){right--;}//找到比基准值小的值arr[hole] = arr[right];hole = right;while (left<right && arr[left]<=key){left++;}//找到比基准值大的值arr[hole] = arr[left];hole = left;}//right和left相遇arr[hole] = key;return hole;
}void QuickSort(int* arr, int left, int right)//排升序
{if (left >= right){return;}//找基准值int keyi = Hole_QuickSort(arr, left, right);//二分//[left,keyi-1] keyi [keyi+1,right]QuickSort(arr, left, keyi - 1);QuickSort(arr, keyi + 1, right);}
前后指针版本:
排升序思路:
设立两个变量:pcur(用于探路,来找比基准值小的值),prev(在pcur的后面)
1、当找到比基准值小的值时,++prev,prev所指向的元素和pcur所指向的元素交换,然后++pcur
2、当pcur所指向的元素没有比基准值小时,++pcur
当pcur越界(pcur>right)时,就将基准值与prev所指向的元素交换,就这样就实现了将比基准值小的元素放在基准值左边,大的放在右边
注:
有时候prev++后的值正好等于pcur,这个时候就不需要发生交换
代码部分:
int lomuto_QuickSort(int* arr, int left, int right)
{int prev = left, pcur = prev + 1;int keyi = left;while (pcur <= right){if (arr[pcur] < arr[keyi]&&++prev != pcur){Swap(&arr[prev], &arr[pcur]);}pcur++;}Swap(&arr[prev], &arr[keyi]);keyi = prev;return keyi;
}void QuickSort(int* arr, int left, int right)//排升序
{if (left >= right){return;}//找基准值int keyi = lomuto_QuickSort(arr, left, right);//二分//[left,keyi-1] keyi [keyi+1,right]QuickSort(arr, left, keyi - 1);QuickSort(arr, keyi + 1, right);}
时间复杂度:
快速排序算法的时间复杂度为O(NlogN),在特殊情况下:待排数组中重复元素很多的时候,会到造成时间复杂度上升为O(N^2logN),这一点要记住,这与如何解决这一情况,在后面的文章中会着重讲解
快速排序(非递归版本)
我们讲解了递归版本的快速排序,那也会有非递归版本的快速排序
在非递归版本的快速排序和递归版本的快速排序有什么区别呢?
非递归版本的快速排序算法需要借助数据结构:栈来实现
思路:
我们首先需要建立一个栈,然后:
1、将数组的left和right下标入栈
2、进入一个循环(结束条件:栈为空),将从栈中出来的两个元素命名为begin和end
3、然后对[begin,end]这个区间来找基准值,找基准值的方法在上面已经说了三种方法,随便用那个都行
4、找完以后,根据基准值进行二分为左右两个子序列,再将左右两个子序列的首尾下标入栈,再重复上面的操作
注意:
1、当begin大于或等于keyi-1或者end小于或等于keyi+1时不进行入栈操作,也就是只有在begin<keyi-1或end>keyi+1的情况下才允许入栈操作
2、每次找完基准值后还要确定一次待排区间中下标是否都入栈了,首尾下标要再入一次栈,入栈条件也要满足上面的条件
3、建立了栈,在排完序后就需要进行销毁
如果对栈还有所不解的朋友,可以移步至【数据结构初阶】栈和队列的建立_实现线性表、栈和队列(要求顺序和链式两种实现)-CSDN博客
其实非递归版快速排序就是利用栈这一数据结构来模拟实现正常快速排序中的递归过程
代码部分(找基准值部分用的是前后指针方法):
void QuickSortNonR(int* arr, int left, int right)//非递归版本
{ST st;StackInit(&st);StackPush(&st, right);StackPush(&st, left);while (!StackEmpty(&st)){int begin = StackTop(&st);StackPop(&st);int end = StackTop(&st);StackPop(&st);int keyi = lomuto_QuickSort(arr, begin, end);if (end > keyi + 1){StackPush(&st, end);StackPush(&st, keyi+1);}if (begin < keyi - 1){StackPush(&st, keyi - 1);StackPush(&st, begin);}}StackDestroy(&st);}
归并排序
思路:
将待排序数组不断进行二分,直到划分为一个个有序的子序列,然后再将这些子序列两两合并,成一个有序数组
也就是先二分再合并
排升序步骤:
1、二分:
对数组取中间值(mid),进行二分,要保证数组最左边下标left要小于最右边下标right(left<right)
mid = left+(right-left)/2
根据mid分为左右两个子序列([left,mid-1],[mid+1,right])
直到left大于或等于right时停止二分
2、合并:
将相邻有序数组两两合并为一个有序数组,并将这个有序数组存储在一个临时数组(temp)中
要注意的是:每次放入临时数组结束后,两个数组中可能会有元素没有放入到临时数组中,所以循环结束后要对两个数组进行检查,再进行一次放入临时数组
3、将临时数组中元素放回原先数组中
代码部分:
void _MergeSort(int* arr, int left, int right, int* temp)
{//二分if (left >= right){return;}int mid = left + (right - left) / 2;_MergeSort(arr, left, mid,temp);_MergeSort(arr, mid+1, right,temp);//合并int begin1 = left, end1 = mid;int begin2 = mid+1, end2 = right;int i = begin1;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2]){temp[i++] = arr[begin1++];}else{temp[i++] = arr[begin2++];}}//两个区间可能还有元素没有入tempwhile (begin1 <= end1){temp[i++] = arr[begin1++];}while (begin2 <= end2){temp[i++] = arr[begin2++];}//将temp中元素放回原数组中for (int i = left; i <= right; ++i){arr[i] = temp[i];}
}void MergeSort(int* arr, int n)
{int* temp = (int*)malloc(sizeof(int) * n);_MergeSort(arr, 0, n - 1, temp);free(temp);
}
时间复杂度:
归并排序算法时间复杂度为O(NlogN),它二分的次数为logN次,合并次数为N次
非比较排序
计数排序
思路:
1、
先找出数组中的最大、最小值,
用最大值和最小值来求出待排数组中元素的出现次数数组大小
用一次数组来存储元素出现次数:count,它的大小为range = max-min+1
2、
遍历数组,求出待排数组中各个元素出现的次数
将每个元素和最小值相减可以得出它在countg数组中的下标,则该对应下标存储的值就加一
3、
根据count数组向原数组中放入元素
arr[index] = i + min
注:
当min和max跨度很大时就会造成空间的浪费,那就不适合这种算法
代码部分:
void CountSort(int* arr, int n)
{//先找最大值和最小值int max = arr[0], min = arr[0];for (int i = 1; i < n; ++i){if (arr[i] > max){max = arr[i];}if (arr[i] < min){min = arr[i];}}int range = max - min + 1;int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc,fail!");}//初始化数组memset(count, 0, sizeof(int*) * range);//统计次数for (int i = 0; i < n; ++i){count[arr[i] - min]++;}//将count中出现的次数还原到原数组中int index = 0;for (int i = 0; i < range; ++i){while (count[i]--){arr[index++] = i + min;}}
}
时间复杂度:
排序算法复杂度及稳定性分析
排序方法 | 平均情况 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 |
冒泡排序 | O(N^2) | O(N) | O(N^2) | O(1) | 稳定 |
直接选择排序 | O(N^2) | O(N^2) | O(N^2) | O(1) | 不稳定 |
直接插入排序 | O(N^2) | O(N) | O(N^2) | O(1) | 稳定 |
希尔排序 | O(NlogN)~O(N^2) | O(1.3) | O(N^2) | O(1) | 不稳定 |
堆排序 | O(NlogN) | O(NlogN) | O(NlogN) | O(1) | 不稳定 |
归并排序 | O(NlogN) | O(NlogN) | O(NlogN) | O(N) | 稳定 |
快速排序 | O(NlogN) | O(NlogN) | O(N^2) | O(logn)~O(N) | 不稳定 |
相关文章:
八大排序算法细讲
目录 排序 概念 运用 常见排序算法 插入排序 直接插入排序 思想: 步骤(排升序): 代码部分: 时间复杂度: 希尔排序 思路 步骤 gap的取法 代码部分: 时间复杂度: 选择排序 直接选…...
机器学习9-卷积和卷积核2
机器学习9-卷积和卷积核2 卷积与边缘提取边缘的种类边缘检测图像求导解析示例 图像求导公式:解析总结 图像梯度噪声的影响 边缘检测目标非极大值抑制总结 卷积与边缘提取 边缘:图像中亮度明显而急剧变化的点 为什么要研究边缘? 编码图像中…...
微服务知识——微服务拆分规范
文章目录 一、微服务拆分规范1、高内聚、低耦合2、服务拆分正交性原则3、服务拆分层级最多三层4、服务粒度适中、演进式拆分5、避免环形依赖、双向依赖6、通用化接口设计,减少定制化设计7、接口设计需要严格保证兼容性8、将串行调用改为并行调用,或者异步…...
【回溯+剪枝】单词搜索,你能用递归解决吗?
文章目录 79. 单词搜索解题思路:回溯(深搜) 剪枝 79. 单词搜索 79. 单词搜索 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 …...
deepseek接入pycharm 进行AI编程
要将DeepSeek接入PyCharm进行AI编程,可以按照以下步骤操作: ### 1. 获取DeepSeek API访问权限 DeepSeek通常以API的形式对外提供服务,你需要在其官方网站注册账号,申请API访问权限。在申请通过后,会获得API密钥(API Key),这是后续调用API的关键凭证。 ### 2. 安装必要…...
M系列/Mac安装配置Node.js全栈开发环境(nvm+npm+yarn)
一、安装 nvm(Node Version Manager) 打开终端,使用 curl 在 M 系列 Mac 上安装 nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash对于非 M 系列的 Intel Mac,上述命令同样适…...
常见Linux命令的复习
常见命令 ls 列出工作目录 ls -l:以长格式显示目录下的文件和子目录信息。ls -a:显示所有文件和子目录,包括隐藏文件 ll 列出该目录下的详细信息 看到该目录下的所有目录和文件的详细信息 cd 切换当前工作目录里 cd /path/to/directory&…...
朴素贝叶斯算法相关文献
朴素贝叶斯是一种基于概率的简单但强大的分类算法。尽管其“朴素”假设(特征之间相互独立)在现实中往往不成立,但在许多实际应用中,它依然表现出色,尤其是在文本分类、垃圾邮件过滤和情感分析等领域。近年来࿰…...
【鸿蒙HarmonyOS Next实战开发】多媒体视频播放-ijkplayer
简介 ijkplayer是OpenHarmony和HarmonyOS环境下可用的一款基于FFmpeg的视频播放器。 演示 下载安装 ohpm install ohos/ijkplayer使用说明 import { IjkMediaPlayer } from "ohos/ijkplayer";import type { OnPreparedListener } from "ohos/ijkplayer";i…...
jvm - GC篇
如何减慢一个对象进入老年代的速度,如何降低GC的次数 堆内存细分 年轻代(Young Generation): 新创建的对象首先被分配在年轻代中。年轻代又被进一步划分为一个Eden区和两个Survivor区(通常称为S0和S1)。…...
edu小程序挖掘严重支付逻辑漏洞
edu小程序挖掘严重支付逻辑漏洞 一、敏感信息泄露 打开购电小程序 这里需要输入姓名和学号,直接搜索引擎搜索即可得到,这就不用多说了,但是这里的手机号可以任意输入,只要用户没有绑定手机号这里我们输入自己的手机号抓包直接进…...
职责链模式
介绍 避免将请求发送者和接收者耦合在一起,让多个对象都有机会接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。 处理请求的对象组成一条链(职责链),职责链可…...
数据分析:企业数字化转型的金钥匙
引言:数字化浪潮下的数据金矿 在数字化浪潮席卷全球的背景下,有研究表明,只有不到30%的企业能够充分利用手中掌握的数据,这是否让人深思?数据已然成为企业最为宝贵的资产之一。然而,企业是否真正准备好从数…...
将Windows下的USB设备共享给WSL(ubuntu)
前言 本文用于学习记录,文中提到的方法也来自于网上资料,如有不对请指出,谢谢! 微软官方参考链接:https://learn.microsoft.com/zh-cn/windows/wsl/connect-usb 如果没有特殊标注,以下命令均在Windows终…...
UG NX二次开发(Python)-API函数介绍与应用实例(三)-UFLayer类操作
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1 前言2、UFLayer类说明3、获取当前工作图层4、移动对象到特定的图层1 前言 采用Python语言进行UG NX二次开发的帮助材料很少,采用录制的方法是一种比较容易实现的方式,但是使用UFun函数更容易上…...
【PostgreSQL内核学习 —— (WindowAgg(三))】
WindowAgg set_subquery_pathlist 部分函数解读check_and_push_window_quals 函数find_window_run_conditions 函数执行案例总结 计划器模块(set_plan_refs函数)set_windowagg_runcondition_references 函数执行案例 fix_windowagg_condition_expr 函数f…...
案例1.spark和flink分别实现作业配置动态更新案例
目录 目录 一、背景 二、解决 1.方法1:spark broadcast广播变量 a. 思路 b. 案例 ① 需求 ② 数据 ③ 代码 2.方法2:flink RichSourceFunction a. 思路 b. 案例 ① 需求 ② 数据 ③ 代码 ④ 测试验证 测试1 测试2 测试3 一、背景 在实时作业(如 Spark Str…...
一键掌握多平台短视频矩阵营销/源码部署
短视频矩阵系统的介绍与应用 随着数字化营销策略的不断演进,传统的短视频矩阵操作方法可能已显陈旧。为此,一款全新的短视频矩阵系统应运而生,它通过整合多个社交媒体账户、创建多样化的任务、运用先进的智能视频编辑工具、实现多平台内容的…...
如何利用maven更优雅的打包
最近在客户现场部署项目,有两套环境,无法连接互联网,两套环境之间也是完全隔离,于是问题就来了,每次都要远程到公司电脑改完代码,打包,通过网盘(如果没有会员,上传下载慢…...
Win11非虚拟机安装ISE14.7
官网下载6.18GB 的 Full Installer for Windows 7/XP/Server解压后运行安装程序不勾选Enable WebTalk to send software, IP ...安装程序卡死在ISE:Configure WebTalk,此时打开任务管理器,在详情中找到xwebtalk,右键结束任务。安装程序继续进…...
大彩讲堂:掌握虚拟屏调试的方法
一、适合范围 适合全系列大彩协议串口屏产品 二、开发环境版本 1. VisualTFT软件版本:V3.0.0.1037及以上的版本,版本查看方式: (1) 打开VisualTFT软件启动页面如图2-1所示,右上角显示的软件版本号; 图2-1 软件版本 (…...
k8sollama部署deepseek-R1模型,内网无坑
这是目录 linux下载ollama模型文件下载到本地,打包迁移到k8s等无网络环境使用下载打包ollama镜像非k8s环境使用k8s部署访问方式非ollama运行deepseek模型linux下载ollama 下载后可存放其他服务器 curl -L https://ollama.com/download/ollama-linux-amd64.tgz -o ollama-linu…...
2025职业发展规划
2025职业发展规划 我是一名大公司的高级移动应用开发技术专家,目前参与了鸿蒙App开发,对鸿蒙的TS语言也有所了解。现在需要制定2025年的职业发展规划,包括学习内容和方向,并以思维导图的形式呈现。我需要梳理出合适的发展路径。首…...
VDN 微服务架构搭建篇(三)基于 Nacos 的 Spring Cloud Gateway 动态路由管理
VDN 微服务架构搭建篇(三):基于 Nacos 的 Spring Cloud Gateway 动态路由管理 在微服务架构中,网关 是整个系统的入口,负责 流量管理、请求路由、安全控制等关键功能。 Spring Cloud Gateway 作为 Spring 生态官方推荐…...
(3)yaml语法
yaml语法 YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。 通俗的来说yaml…...
SpringAI系列 - 使用LangGPT编写高质量的Prompt
目录 一、LangGPT —— 人人都可编写高质量 Prompt二、快速上手2.1 诗人 三、Role 模板3.1 Role 模板3.2 Role 模板使用步骤3.3 更多例子 四、高级用法4.1 变量4.2 命令4.3 Reminder4.4 条件语句4.5 Json or Yaml 方便程序开发 一、LangGPT —— 人人都可编写高质量 Prompt La…...
Linux提权--John碰撞密码提权
John the Ripper(简称 John)是一个常用的密码破解工具,可以通过暴力破解、字典攻击、规则攻击等方式,尝试猜解用户密码。密码的弱度是提权攻击中的一个重要因素,如果某个用户的密码非常简单或是默认密码࿰…...
系分成长指南
持续改进的核心理念:持续发现问题并改进,通过反馈和反馈循环优化工作流程。 如何制定反馈渠道:通过线上表格填写问卷、内部会议记录、即时消息等方式。 如何保持动力:设定具体目标、使用 KPI 测量进展、奖励机制、建立支持体系。 …...
5 计算机网络
5 计算机网络 5.1 OSI/RM七层模型 5.2 TCP/IP协议簇 5.2.1:常见协议基础 一、 TCP是可靠的,效率低的; 1.HTTP协议端口默认80,HTTPSSL之后成为HTTPS协议默认端口443。 2.对于0~1023一般是默认的公共端口不需要注册,1024以后的则需…...
绿联NAS安装cpolar内网穿透工具实现无公网IP远程访问教程
文章目录 前言1. 开启ssh服务2. ssh连接3. 安装cpolar内网穿透4. 配置绿联NAS公网地址 前言 本文主要介绍如何在绿联NAS中使用ssh远程连接后,使用一行代码快速安装cpolar内网穿透工具,轻松实现随时随地远程访问本地内网中的绿联NAS,无需公网…...
Temperature、Top-P、Top-K、Frequency Penalty详解
在生成式AI(比如ChatGPT)中,Temperature、Top-P、Top-K、Frequency Penalty 这些参数用于控制文本生成的多样性、随机性和重复度,它们的作用如下: 1. Temperature(温度) 作用:控制输…...
2.6作业
1.思维导图 2.代码解释 struct A{double a; }; struct B{char b[8]; };int main(int argc,const char *argv[]) {struct A x;struct B y;x.a 3.14;y *(struct B*)&x;printf("y.b %lf\n",*(double *)y.b);return 0; } 注释: 1. 定义struct A类型变…...
面试笔记-多线程篇
为什么不直接调用run方法而是调用start方法? start方法会先创建一条线程,再用创建出的新线程去执行对应的run方法,这样才是起到多线程效果,如果直接调用run方法,则只是在原线程执行。 线程的sleep方法和wait方法的区别…...
stacking 框架
stacking stacking介绍 Stacking是个多层的多模型集合方法。每一层都可包括多个模型,下一层利用上一层模型的结果进行学习。可以只使用一层,然后用元学习器融合,也可以多层融合。 单层融合 多层融合 如上图所示,Stacking结构中…...
面向对象编程简介
面向对象编程(OOP)是一种编程范式,强调通过“对象”来设计软件。对象是数据和功能的封装,使得程序更易于理解和维护。本文将介绍面向对象的基本概念、特性以及其在软件开发中的重要性。 1. 面向对象的基本概念 1.1 对象 对象是…...
【ArcGIS_Python】使用arcpy脚本将shape数据转换为三维白膜数据
说明: 该专栏之前的文章中python脚本使用的是ArcMap10.6自带的arcpy(好几年前的文章),从本篇开始使用的是ArcGIS Pro 3.3.2版本自带的arcpy,需要注意不同版本对应的arcpy函数是存在差异的 数据准备:准备一…...
云计算——AWS Solutions Architect – Associate(saa)1、什么是云,AWS介绍
什么是云? 什么是云? 云计算(cloud computing)是基于互联网的相关服务的增加、使用和交付模式,通常涉及通过互联网来提供动态易护展且经常是虚拟化的资源。云是网络、互联网的一种比喻说法。 简单理解为:云是 共享资源,按需付费࿰…...
快手ip属地是定位吗?怎么改
在当今数字化时代,随着网络平台的不断发展,用户隐私和数据安全成为了公众关注的焦点。各大社交媒体平台纷纷推出的“IP属地”功能,无疑为网络环境增添了一抹新的色彩。其中,快手的IP属地显示功能尤为引人注目。那么,快…...
graylog初体验
最近graylog比较火,部署了一个来测试下,看下后续能不能代替目前占用资源比较多的elk,目前未对graylog性能进行深入测试,只是简单体验了下,graylog的UI比较简陋,但是在报警以及权限方面优于ELK,整…...
MySQL实战-解决方案
1. MySQL 主从集群同步延迟问题的解决方案 在主从复制架构中,主库执行写操作后,将更新事件写入 Binlog,从库通过 I/O 线程将 Binlog 数据同步到本地的 Relay Log,再由 SQL 线程解析并执行,从而保持数据一致性。然而&a…...
使用 CSS 实现透明效果
在 CSS 中,实现透明效果有几种方法,具体使用哪种方法取决于具体需求。以下是一些常见的方法: 使用 opacity 属性: opacity 属性可以设置整个元素的透明度,包括其所有的子元素。 .transparent { opacity: 0.5; /* 0 表…...
LabVIEW2025中文版软件安装包、工具包、安装教程下载
下载链接:LabVIEW及工具包大全-三易电子工作室http://blog.eeecontrol.com/labview6666 《LabVIEW2025安装图文教程》 1、解压后,双击install.exe安装 2、选中“我接受上述2条许可协议”,点击下一步 3、点击下一步,安装NI Packa…...
2025.2.5——五、[网鼎杯 2020 青龙组]AreUSerialz
题目来源:BUUCTF [网鼎杯 2020 青龙组]AreUSerialz 一、打开靶机,整理信息 直接得到一串php代码,根据题目可以看到还有序列化 二、解题思路 step 1:代码审计 <?phpinclude("flag.php");highlight_file(__FILE__…...
Oracle Life DBA的一天
/***************************************************************************************************************** Navicat Premium Data Transfer Source File : Oracle Life DBA的一天.sql Source Server Type : Oracle Source Server Version : 190…...
手写MVVM框架-实现简单v-bind
v-bind 有两种情况: 1.绑定的是一个简单的属性 <div :class"customClass">简单v-bind</div> 2.绑定的元素上面有表达式 <div :class"{customClass: a 1 > 2}">简单v-bind</div> 这一章我们先说第一种情况&…...
【力扣】240.搜索二维矩阵 II
题目 我的代码 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {for(int i0;i<matrix.size();i){for(int j0;j<matrix[0].size();j){if(targetmatrix[i][j]){return true;}else if(target<matrix[i][j]){brea…...
PlanLLM: 首个支持开放词汇与封闭集任务的跨模态视频程序规划框架
2025年1月7号,由杨德杰、赵子敬、刘洋联合提出PlanLLM,一种基于可微调大型语言模型(LLM)的跨模态联合学习框架,用于解决视频程序规划任务。通过引入LLM增强规划模块和互信息最大化模块,PlanLLM突破了现有方…...
使用服务器部署DeepSeek-R1模型【详细版】
文章目录 引言deepseek-r1IDE或者终端工具算力平台体验deepseek-r1模型总结 引言 在现代的机器学习和深度学习应用中,模型部署和服务化是每个开发者面临的重要任务。无论是用于智能推荐、自然语言处理还是图像识别,如何高效、稳定地将深度学习模型部署到…...
TCP三次握手、四次挥手过程及原理
TCP 协议简述 TCP 提供面向有连接的通信传输,面向有连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接。 无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接…...
AWS App2Container
AWS App2Container 是一个由 Amazon Web Services (AWS) 提供的工具,它帮助用户将现有的传统应用程序(特别是运行在虚拟机或物理服务器上的应用)转化为容器化的应用,从而可以在 AWS 上更方便地部署、管理和扩展。具体来说…...