😘个人主页:@Cx330❀

👀个人简介:一个正在努力奋斗逆天改命的二本觉悟生

📖个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》

前言:今天这篇博客就给大家将一个计数排序,然乎就给大家总结一下所有的排序算法的时间复杂度,空间复杂度,稳定性进行一个归纳总结。


目录

一、计数排序

核心步骤:

代码实现:

测试结果:

计数排序的特性:

二.排序算法复杂度及稳定性分析

各排序算法对比表:

代码展现:

Sort.c:

Sort.h:

test.c:


一、计数排序

计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。
思路:
  • 统计相同元素出现次数
  • 根据统计的结果将序列回收到原来的序列中

核心步骤:

1. 确定数据范围

遍历数组,找到最大值和最小值,然后计算数据范围range=max-min+1确定数组的空间(避免空间浪费)

2. 统计元素出现次数

创建一个计数数组count,空间大小为range,并且要给count初始化(calloc或者memset),遍历原数组,将每个元素 arr[i] 映射到 count[arr[i] - min](减去 min 是为了处理包含负数的情况,一定要用arr[i]-min),统计每个值的出现次数。

3. 将count数组中的数据排序还原到原数组中

再定义一个index变量,作为原数组的下标,遍历count数组,根据count[i]统计到的个数进行映射i+min就是原数组的值,循环次数等于该值出现的次数,将数组的原始数据值放入arr原始数组中(对应原始值一定是i+min)

代码实现:

//非比较排序--计数排序
void CountSort(int* arr, int n)
{int min = arr[0], max = arr[0];for (int i = 0; i < n; i++){if (arr[i] < min){min = arr[i];}if (arr[i] > max){max = arr[i];}}//确定count数组大小int range = max - min + 1;int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc fail!");exit(1);}//对count初始化memset(count, 0, sizeof(int) * range);for (int i = 0; i < n; i++){count[arr[i] - min]++;}//将count数组映射到arr数组中int index = 0;for (int i = 0; i < range; i++){while (count[i]--){arr[index++] = i + min ;}}
}

test.c:

#include"Sort.h"
void printArr(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}void test01()
{int a[] = { 5,3,9,6,2,4,7,1,8 };//int a[] = { 6,1,2,7,9,3 };int n = sizeof(a) / sizeof(a[0]);printf("排序之前:");printArr(a, n);//InsertSort(a, n);//ShellSort(a, n);//SelectSort(a, n);//HeapSort(a, n);//BubbleSort(a, n);//QuickSort(a, 0, n - 1);//QuickSortNorR(a, 0, n - 1);//MergeSort(a, n);CountSort(a, n);//MergeSortNonR(a, n);printf("排序之后:");printArr(a, n);
}void TestOP()
{srand(time(0));const int N = 100000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);int* a3 = (int*)malloc(sizeof(int) * N);int* a4 = (int*)malloc(sizeof(int) * N);int* a5 = (int*)malloc(sizeof(int) * N);int* a6 = (int*)malloc(sizeof(int) * N);int* a7 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){a1[i] = rand();a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];}int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();ShellSort(a2, N);int end2 = clock();int begin3 = clock();SelectSort(a3, N);int end3 = clock();int begin4 = clock();HeapSort(a4, N);int end4 = clock();int begin5 = clock();QuickSort(a5, 0, N - 1);int end5 = clock();int begin6 = clock();MergeSort(a6, N);int end6 = clock();int begin7 = clock();BubbleSort(a7, N);int end7 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("MergeSort:%d\n", end6 - begin6);printf("BubbleSort:%d\n", end7 - begin7);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);free(a7);
}int main()
{test01();//TestOP();return 0;
}

测试结果:

测试完成,打印没有问题,升序排序正确,退出码为0 

计数排序的特性:

  • 计数排序在数据范围集中时,效率很高,但是适用范围以及场景有限
  • 时间复杂度:O(n+range)
  • 空间复杂度:O(range)
  • 稳定性:稳定

二.排序算法复杂度及稳定性分析

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

各排序算法对比表:

其中冒泡排序,直接插入排序,归并排序是稳定的,这里就不过多介绍了,我们主要通过一些特例来看下那些不稳定的排序算法。至于时间复杂度和空间复杂度,博主大部分都在前面的博客中分享过了。

1.直接选择排序:

2.希尔排序:

3.堆排序:

4.快速排序:

代码展现:

Sort.c:

#include"Sort.h"
#include"stack.h"
//1)直接插入排序
void InsertSort(int* arr, int n)
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = arr[end + 1];while (end >= 0){if (arr[end] > tmp){arr[end + 1] = arr[end];end--;}else{break;}}arr[end + 1] = tmp;}
}//2)希尔排序
void ShellSort(int* arr, int n)
{int gap = n;while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < n - gap; i++){int end = i;int tmp = arr[end + gap];while (end >= 0){if (arr[end] > tmp){arr[end + gap] = arr[end];end-=gap;}else{break;}}arr[end + gap] = tmp;}}
}void Swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
//向下调整
void AdjustDown(int* arr, int parent, int n)
{int child = parent * 2 + 1;while (child < n){ //找大的孩子//建大堆 <//建小堆 >if (child + 1 < n && arr[child] < arr[child + 1]){child++;}//孩子和父亲比较//建大堆 <//建小堆 >if (arr[parent] < arr[child]){Swap(&arr[parent], &arr[child]);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);//因为这里建的是小堆,所以向下调整,就成了降序}//向上调整算法--建堆  时间复杂度O(n*logn)/*for (int i = 0; i < n; i++){AdjustUp(arr, i);}*///n* lognint end = n - 1;while (end > 0)//循环取最后一个元素与顶交换,再向下调整{Swap(&arr[0], &arr[end]);AdjustDown(arr, 0, end);end--;}
}//冒泡排序
void BubbleSort(int* arr, int n)
{int change = 1;for (int i = 0; i < n-1; i++){for (int j = 0; j < n - 1 - i; j++){if (arr[j] > arr[j + 1]){Swap(&arr[j], &arr[j + 1]);change = 0;}}if (change == 1){break;}}
}//1)直接选择排序
//void SelectSort(int* arr, int n)
//{
//	for (int i = 0; i < n; i++)
//	{
//		int mini = i;
//		for (int j = i + 1; j < n; j++)
//		{
//			if (arr[j] < arr[mini])
//			{
//				mini = j;
//			}
//		}
//		Swap(&arr[mini], &arr[i]);
//	}
//}//直接选择排序
void SelectSort(int* arr, int n)
{int begin = 0, end = n - 1;while (begin < end){int mini = begin;int maxi = begin;for (int i = begin+1; i <= end; i++){if (arr[i] < arr[mini]){mini = i;}if (arr[i] > arr[maxi]){maxi = i;}}//交换if (begin == maxi){maxi = mini;}Swap(&arr[begin], &arr[mini]);Swap(&arr[end], &arr[maxi]);begin++;end--;}
}//找基准值--hoare版本
int _QuickSort1(int* arr, int left, int right)
{int keyi = left;left++;while (left <= right){//right从右往左找比基准值小的,如果大于基准值就--while (left <= right && arr[right] > arr[keyi]){--right;}//left从左往右找比基准值大的,如果小于基准值就++while (left <= right && arr[left] < arr[keyi]){++left;}//left和right交换if(left<=right)Swap(&arr[left++], &arr[right--]);}//right位置就是基准值的位置Swap(&arr[right], &arr[keyi]);return right;
}//找基准值--挖坑法
int _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;}arr[hole] = key;return hole;
}//找基准值--lumoto双指针法
int _QuickSort2(int* arr, int left, int right)
{int prev = left, cur = prev + 1;int keyi = left;while (cur < right){if (arr[cur] < arr[keyi] && ++prev != cur){Swap(&arr[cur], &arr[prev]);}++cur;}Swap(&arr[prev], &arr[keyi]);return prev;
}//快速排序
void QuickSort(int* arr, int left, int right)
{if (left >= right){return;}//找基准值keyiint keyi = _QuickSort(arr, left, right); //左序列[left,keyi-1]右序列[keyi+1,right]QuickSort(arr, left, keyi - 1);QuickSort(arr, keyi + 1, right);
}//找基准值非递归版--栈
void QuickSortNorR(int* arr, int left, int right)
{ST st;STInit(&st);STPush(&st, right);STPush(&st, left);while (!STEmpty(&st)){//取栈顶两次int begin = STTop(&st);STPop(&st);int end = STTop(&st);STPop(&st);//[begin,end]--找基准值int keyi = begin;int prev = begin, cur = prev + 1;while (cur <= end){if (arr[cur] < arr[keyi] && ++prev != cur){Swap(&arr[cur], &arr[prev]);}++cur;}Swap(&arr[prev], &arr[keyi]);keyi = prev;if (keyi + 1 < end){STPush(&st, end);STPush(&st, keyi+1);}if (begin < keyi - 1){STPush(&st, keyi - 1);STPush(&st, begin);}}STDesTroy(&st);
}void _MergeSort(int* arr, int left, int right,int*tmp)
{//分解if (left >= right){return;}//根据mid将[left,right]划分为左右两个序列[left,mid] [mid+1,right]int mid = left + (right - left) / 2;_MergeSort(arr, left, mid,tmp);_MergeSort(arr, mid+1, right,tmp);//合并[left,mid] [mid+1,right]int begin1 = left, end1 = mid;int begin2 = mid+1, end2 = right;int index = left;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2]){tmp[index++] = arr[begin1++];}else{tmp[index++] = arr[begin2++];}}//要么begin1越界 //要么begin2越界while (begin1 <= end1){tmp[index++] = arr[begin1++];}while (begin2 <= end2){tmp[index++] = arr[begin2++];}for (int i = left; i <= right; i++){arr[i] = tmp[i];}
}//归并排序
void MergeSort(int* arr, int n)
{int* tmp = (int*)malloc(sizeof(int)*n);//[0,n-1]_MergeSort(arr, 0, n - 1,tmp);free(tmp);tmp = NULL;
}//非比较排序--计数排序
void CountSort(int* arr, int n)
{int min = arr[0], max = arr[0];for (int i = 0; i < n; i++){if (arr[i] < min){min = arr[i];}if (arr[i] > max){max = arr[i];}}//确定count数组大小int range = max - min + 1;int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc fail!");exit(1);}//对count初始化memset(count, 0, sizeof(int) * range);for (int i = 0; i < n; i++){count[arr[i] - min]++;}//将count数组映射到arr数组中int index = 0;for (int i = 0; i < range; i++){while (count[i]--){arr[index++] = i + min ;}}
}//归并排序--非递归版本
void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail!\n");exit(1);}int gap = 1;while (gap < n){//根据gap划分组,两两合并for (int i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;int index = begin1;//处理奇数个数据if (begin2 >= n){break;}if (end2 >= n){end2 = n - 1;}//合并while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[index++] = a[begin1++];}else{tmp[index++] = a[begin2++];}}while (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}//tmp导入到a数组中memcpy(a + i, tmp+i, sizeof(int)*(end2 - i + 1));}gap *= 2;}free(tmp);
}

Sort.h:

#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<time.h>
//插入排序
//1)直接插入排序
void InsertSort(int* arr, int n);
//2)希尔排序
void ShellSort(int* arr, int n);//选择排序
//1)直接选择排序
void SelectSort(int* arr, int n);
//2)堆排序
void HeapSort(int* arr, int n);
//冒泡排序
void BubbleSort(int* arr, int n);
//快速排序
void QuickSort(int* arr, int left, int right);
//找基准值非递归版--栈
void QuickSortNorR(int* arr, int left, int right);
//归并排序--递归版本
void MergeSort(int* arr, int n);
//非比较排序--计数排序
void CountSort(int* arr, int n);
//归并排序--非递归版本
void MergeSortNonR(int* a, int n);

test.c:

#include"Sort.h"
void printArr(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}void test01()
{int a[] = { 5,3,9,6,2,4,7,1,8 };//int a[] = { 6,1,2,7,9,3 };int n = sizeof(a) / sizeof(a[0]);printf("排序之前:");printArr(a, n);//InsertSort(a, n);//ShellSort(a, n);//SelectSort(a, n);//HeapSort(a, n);//BubbleSort(a, n);//QuickSort(a, 0, n - 1);//QuickSortNorR(a, 0, n - 1);//MergeSort(a, n);CountSort(a, n);//MergeSortNonR(a, n);printf("排序之后:");printArr(a, n);
}void TestOP()
{srand(time(0));const int N = 100000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);int* a3 = (int*)malloc(sizeof(int) * N);int* a4 = (int*)malloc(sizeof(int) * N);int* a5 = (int*)malloc(sizeof(int) * N);int* a6 = (int*)malloc(sizeof(int) * N);int* a7 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){a1[i] = rand();a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];}int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();ShellSort(a2, N);int end2 = clock();int begin3 = clock();SelectSort(a3, N);int end3 = clock();int begin4 = clock();HeapSort(a4, N);int end4 = clock();int begin5 = clock();QuickSort(a5, 0, N - 1);int end5 = clock();int begin6 = clock();MergeSort(a6, N);int end6 = clock();int begin7 = clock();BubbleSort(a7, N);int end7 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("MergeSort:%d\n", end6 - begin6);printf("BubbleSort:%d\n", end7 - begin7);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);free(a7);
}int main()
{test01();//TestOP();return 0;
}

往期回顾:

【数据结构初阶】--排序(一):直接插入排序,希尔排序

【数据结构初阶】--排序(二):直接选择排序,堆排序

【数据结构初阶】--排序(三):冒泡排序、快速排序

【数据结构初阶】--排序(四):归并排序

总结:这篇博客到此为止,排序的数据结构就已经全部写完了,数据结构初阶也就结束了,后续我还会写一些某些排序的进阶,然后就正式进入C++的学习了。我们数据结构初阶讲这些数据结构都是用C语言实现的,还有些比较难的数据结构在后续C++的学习中我们也会接触到,但是利用C++来实现就方便很多了,如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。

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

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

相关文章

Incredibuild 新增 Unity 支持:击破构建时间过长的痛点

任何开发过复杂 Unity 项目的团队都会告诉你&#xff1a;构建速度已成为生产流程中的核心痛点。Unity 灵活且强大&#xff0c;但随着项目规模扩大&#xff08;尤其是包含 3D 资源、复杂着色器和庞大内容管线的项目&#xff09;&#xff0c;构建过程会逐渐变成一项隐性成本。 多…

大数据接口 - 收入评估(社保评级)API

请求端点 {"post": "https://api.tianyuanapi.com/api/v1/JRZQ09J8?t13位时间戳" }请求头字段名类型必填描述Access-Idstring是账号的 Access-Id对于业务请求参数 通过加密后得到 Base64 字符串&#xff0c;将其放入到请求体中&#xff0c;字段名为 data&…

C++八股 —— 设计模式

文章目录一、创建型模式1. 单例模式2. 工厂模式二、结构型模式1. 装饰器模式2. 代理模式三、行为型模式1. 观察者模式2. 策略模式一、创建型模式 1. 单例模式 C八股 —— 单例模式_c 单例模式-CSDN博客 2. 工厂模式 参考&#xff1a;【设计模式】工厂模式详解-----简单工厂…

在openeuler中如何使用 firewalld 开放指定端口

在 OpenEuler 中使用 firewalld 开放指定端口的操作步骤如下&#xff0c;需区分临时开放&#xff08;重启后失效&#xff09;和永久开放&#xff08;重启后保留&#xff09;两种场景&#xff1a;一、查询端口当前状态首先确认端口是否已开放&#xff0c;避免重复配置&#xff1…

【Java进阶】Java JIT 编译器深度解析与优化实践

Java JIT 编译器深度解析与优化实践Java JIT 编译器深度解析与优化实践一、JIT 编译器核心原理1. JIT 工作流程2. 热点代码检测机制二、Java 8 JIT 优化升级1. 分层编译优化2. 方法内联增强3. 循环优化升级4. 逃逸分析增强5. 向量化支持三、JIT友好代码设计原则1. 方法设计优化…

【本地部署问答软件Apache Answer】Answer开源平台搭建:cpolar内网穿透服务助力全球用户社区构建

文章目录前言1. 本地安装Docker2. 本地部署Apache Answer2.1 设置语言选择简体中文2.2 配置数据库2.3 创建配置文件2.4 填写基本信息3. 如何使用Apache Answer3.1 后台管理3.2 提问与回答3.3 查看主页回答情况4. 公网远程访问本地 Apache Answer4.1 内网穿透工具安装4.2 创建远…

华为数通认证学习

1、华为人才认证官网&#xff0c;https://e.huawei.com/cn/talent/portal/#/ 很全面的网站&#xff0c;包含了概述、了解认证、参加考试、学习资源、认证资讯四个板块。可以了解华为认证的整个流程、下载学习资源&#xff08;培训教材、视频课程等&#xff09;&#xff0c;以及…

Android-ContentProvider的跨应用通信学习总结

一、ContentProvider的概念1. ContentProvider 是什么&#xff1f;&#xff08;核心概念&#xff09;ContentProvider 是 Android 四大组件之一。它的核心职责是管理和共享应用的结构化数据。我们可以把它想象成一个应用的**“数据大使馆”**。在一个国家里&#xff08;Android…

Java数据结构第二十六期:解密位图,海量数据处理的 “空间魔法”

专栏&#xff1a;Java数据结构秘籍 个人主页&#xff1a;手握风云 目录 一、位图 1.1. 概念 1.2. 面试题 1.3. 位图的实现 1.4. 位图的应用 一、位图 1.1. 概念 在数据结构中&#xff0c;位图&#xff08;也称为位数组、位向量或位集&#xff09;是一种紧凑的方式来表示一…

芯科科技即将重磅亮相IOTE 2025深圳物联网展,以全面的无线技术及生态覆盖赋能万物智联

作为低功耗无线连接领域的创新性领导厂商&#xff0c;Silicon Labs&#xff08;亦称“芯科科技”&#xff09;将于8月27至29日携其最前沿的人工智能&#xff08;AI&#xff09;和物联网&#xff08;IoT&#xff09;解决方案在深圳举办的IOTE 2025国际物联网展中盛大展出。这场亚…

Linux上安装多个JDK版本,需要配置环境变量吗

简短回答&#xff1a;不需要同时配置多个 JDK 的 JAVA_HOME 和 PATH&#xff0c;但你可以安装多个版本&#xff0c;并通过灵活的方式在它们之间切换。 文章目录✅ 正确做法&#xff1a;安装多个 JDK&#xff0c;但只让一个生效&#xff08;通过环境变量或 alternatives&#xf…

MySQL有哪些高可用方案

大家好&#xff0c;我是锋哥。今天分享关于【MySQL有哪些高可用方案】面试题。希望对大家有帮助&#xff1b; MySQL有哪些高可用方案? 超硬核AI学习资料&#xff0c;现在永久免费了&#xff01; MySQL 高可用方案是指确保 MySQL 数据库在面对硬件故障、网络故障、负载过重等…

【Windows】Windows平台基于加速地址安装vcpkg并集成到Visual Studio 2017

基础运行环境 启动&#xff1a; 适用于 VS 2017 的 x64 本机工具命令提示 ninja 下载压缩包 https://gh-proxy.com/https:/github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-win.zip 直接解压到c:/Windows (无需配置环境变量) CMake 下载安装包 https://gh-proxy…

LLMs之MCP:Chrome MCP的简介、安装和使用方法、案例应用之详细攻略

LLMs之MCP&#xff1a;Chrome MCP的简介、安装和使用方法、案例应用之详细攻略 目录 Chrome MCP的简介 1、特点 2、与类似项目的比较 Chrome MCP的安装和使用方法 1、安装 2、使用方法 加载 Chrome 扩展 与 MCP 协议客户端一起使用 使用 STDIO 连接&#xff08;替代方…

【Java EE】多线程-初阶 synchronized 关键字 - 监视器锁 monitor lock

synchronized 关键字 - 监视器锁 monitor lock5. synchronized 关键字 - 监视器锁 monitor lock5.1 synchronized 的特性5.2 synchronized 使⽤⽰例5.3 Java 标准库中的线程安全类本节⽬标• 掌握 synchronized关键字5. synchronized 关键字 - 监视器锁 monitor lock &#xf…

Java多线程:从基础到实战

引言多线程是Java并发编程的核心技术之一&#xff0c;广泛应用于服务器开发、数据处理、实时系统等领域。通过多线程&#xff0c;程序可以充分利用CPU资源&#xff0c;提高执行效率&#xff0c;同时处理多个任务。本文将从多线程的基本概念、实现方式、线程状态、同步与通信到常…

list集合可以一边遍历一遍修改元素吗?

今天看来一下Java中list集合部分的八股&#xff0c;发现了一个以前没注意过的问题&#xff0c;记录一下list可以一边遍历一边修改元素吗&#xff1f;答&#xff1a;在 Java 中&#xff0c;List在遍历过程中是否可以修改元素取决于遍历方式和具体的List实现类。①&#xff1a;对…

Infusing fine-grained visual knowledge to Vision-Language Models

Infusing fine-grained visual knowledge to Vision-Language Models Authors: Nikolaos-Antonios Ypsilantis, Kaifeng Chen, Andr Araujo, Ondřej Chum Deep-Dive Summary: 视觉-语言模型中注入细粒度视觉知识 摘要 大规模对比预训练产生了强大的视觉-语言模型&#xf…

RK3576赋能无人机巡检:多路视频+AI识别引领智能化变革

随着工业巡检任务的复杂度不断提升&#xff0c;无人机逐渐取代传统人工&#xff0c;成为电力、能源、林业、农业等行业的“高空作业主力”。然而&#xff0c;巡检并非简单的拍摄和回放&#xff0c;它要求无人机实时采集多路画面、快速分析异常&#xff0c;并稳定回传数据。这对…

ollama Modelfile 文件生成

输入 根据如下TEMPLATE和params写一个modelfile文件&#xff0c;TEMPLATE为&#xff1a;{{- $lastUserIdx : -1 -}} {{- range $idx, $msg : .Messages -}} {{- if eq $msg.Role “user” }}{{ $lastUserIdx $idx }}{{ end -}} {{- end }} {{- if or .System .Tools }}<|i…