【數據結構初階】--排序(五):計數排序,排序算法復雜度對比和穩定性分析

😘個人主頁:@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…