[數據結構】——七種常見排序

文章目錄

    • 前言
  • 一.冒泡排序
  • 二.選擇排序
  • 三.插入排序
  • 四.希爾排序
  • 五.堆排序
  • 六.快速排序
    • hoare
    • 挖坑法
    • 前后指針
    • 快排遞歸實現:
    • 快排非遞歸實現:
  • 七、歸并排序
    • 歸并遞歸實現:
    • 歸并非遞歸實現:
  • 八、各個排序的對比圖

前言

  • 排序:所謂排序,就是使一串記錄,按照其中的某個或某些關鍵字的大小, 遞增或遞減的排列起來的操作。
  • 穩定性:假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,則稱這種排序算法是穩定的;否則稱為不穩定的。
  • 內部排序:數據元素全部放在內存中的排序。
  • 外部排序:數據元素太多不能同時放在內存中,根據排序過程的要求不能在內外存之間移動數據的排序

接下來會涉及到的排序
在這里插入圖片描述

這里寫了一個測試排序性能的代碼,方便我們觀察各個排序的好壞

//測試排序的性能
void TestOP()
{srand((unsigned)time(NULL));//N的數值手動改變,以判斷性能的好壞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() + 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];}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);
}

還有交換函數

//交換函數
void Swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}


以下排序默認是升序,即從小到大的順序

一.冒泡排序

冒泡的時間復雜度是O(N^2),空間復雜度是O(1),具有穩定性

在這里插入圖片描述

從圖中我們可以看出,冒泡排序其實就是一種選擇排序,即走一次,找到最大的數放在最右邊,接下來要排序的數據就少了一個,再走一次,找到此時最大的數放在此時的最右邊,接下來不斷重復此步驟,數據就有序了

//冒泡排序
void BubbleSort(int* a, int n)
{for (int i = 0; i < n - 1; i++){int flag = 0;for (int j = 0; j < n - 1 - i; j++){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);flag = 1;}}if (flag == 0){return;}}
}

雖然我們使用了flag進行了優化,使冒泡排序在最好的情況下的時間復雜度位O(N),但是實際上冒泡排序只有教學意義,沒有實踐意義,效率非常低
在十萬個數據下面,冒泡走了5s,而在一百萬數據下面,走了接近1min了,可見效率是如此的低下

在這里插入圖片描述
在這里插入圖片描述

二.選擇排序

選擇排序的時間復雜度是O(N^2),空間復雜度是O(1),具有不穩定性

在這里插入圖片描述

從圖中我們可以清楚的看到,選擇排序每走一次,找到最大或者最小的數據放在最右邊或者最左邊,然后減少排序的個數,以此類推完成排序

這個排序方法可以優化一下,即走一次找到最小的同時找到最大的

//選擇排序
void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int mini = begin;int maxi = begin;for (int i = begin + 1; i <= end; i++){if (a[i] < a[mini]){mini = i;}if (a[i] > a[maxi]){maxi = i;}}Swap(&a[begin], &a[mini]);if (maxi == begin){maxi = mini;}Swap(&a[end], &a[maxi]);begin++;end--;}
}

選擇排序即沒有實際意義,也沒有教學意義,效率低下
在十萬個數據下面,選擇走了8s,而在一百萬數據下面,走了接近15min了,效率不行

在這里插入圖片描述
在這里插入圖片描述

三.插入排序

插入排序的時間復雜度是O(N^2),空間復雜度是O(1),具有穩定性
在這里插入圖片描述

插入排序的思路就是假設在[0,end]是有序的數據,在end+1的位置上插入一個新的數據,用tmp保存插入的數據。
如果end位置上的值大于tmp,end就減1,比較此時end位置上的值與tmp的大小
如果end位置上的值小于tmp,退出循環,將tmp賦給end + 1 位置上的值

//插入排序
void InsertSort(int* a, int n)
{for (int i = 0; i < n - 1; i++){int end = i;//[0,end]是有序的,插入[end+1]數據int tmp = a[end + 1];while (end >= 0){if (a[end] > tmp){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}
}

雖然插入排序的時間復雜度是O(N^2),但是它具有實踐意義

在十萬個數據下面,走了1s,在一百萬數據下面,走了16s了,可見效率是還可以

在這里插入圖片描述

在這里插入圖片描述

四.希爾排序

希爾排序的時間復雜度是O(N^1.3),空間復雜度是O(1),不具有穩定性

在這里插入圖片描述

希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進版本。

希爾排序的思想:

  1. 預排序:先分gap,在各自的組內進行插入排序
  2. 插入排序:排好序后,減小gap的值,再次進行預排序,直到gap = 1,進行插入排序,這樣數據就有序了

假設gap = 3,將原數據分成3組,那么第一趟預排序的結果為下圖
在這里插入圖片描述
可以看到在走了一趟后的數據,比原始數據接近有序,這就是希爾排序的優點

//希爾排序
void ShellSort(int* a, 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 = a[end + gap];while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}

在十萬個數據下面,希爾走了31ms,在一百萬數據下面,走了264ms,可見效率還是很快的

在這里插入圖片描述
在這里插入圖片描述

五.堆排序

堆排序的時間復雜度是O(NlogN),空間復雜度是O(1),不具有穩定性

在這里插入圖片描述

堆排序(Heap Sort)是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。

堆排序的基本思想是:

  1. 將待排序序列構造成一個大頂堆,此時,整個序列的最大值就是堆頂的根節點。
  2. 將其與末尾元素進行交換,此時末尾就為最大值。
  3. 然后將剩余n-1 個元素重新構造成一個堆,這樣會得到 n 個元素的次小值。 如此反復執行,便能得到一個有序序列了。
//向下調整法
void AdjustDown(int* a, int n, int parent)
{int child = 2 * parent + 1;while (child < n){if (child + 1 < n && a[child + 1] > a[child]){child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = 2 * parent + 1;}else{break;}}
}//堆排序
void HeapSort(int* a, int n)
{//創建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}//排序int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}

在十萬個數據下面,堆排走了45ms,在一百萬數據下面,走了473ms,效率還可以
在這里插入圖片描述
在這里插入圖片描述

六.快速排序

快速排序的平均時間復雜度是O(NlogN),但是在最壞情況下有可能是O(N^2),空間復雜度是O(logN)~O(N),不具有穩定性
在這里插入圖片描述

快速排序(Quick Sort)是一種常用的排序算法。快速排序的基本思想是通過選擇一個基準元素,將數組分為兩部分,使得左邊的元素都小于等于基準元素,右邊的元素都大于等于基準元素。然后,對左右兩部分分別進行快速排序,直到整個數組有序。

但是當數組已經有序時是最壞情況,快速排序的時間復雜度可能會達到O(N^2)。但是,在大多數情況下,快速排序的時間復雜度都非常接近O (NlogN)

快速排序優化的方法:

1.三數取中

可以看到假定最左邊的數作為基準元素,會不準確,因為有可能是最大的數也有可能是最小的數,影響效率,我們可以選擇三個數中間的數來作為基準元素

//三數取中法  left  midi  right
int GetMidi(int* a,int left,int right)
{int midi = (left + right) / 2;if (a[left] > a[midi]){if (a[midi] >= a[right]){return midi;}else if (a[left] < a[right]){return left;}else{return right;}}else{if (a[midi] <= a[right]){return midi;}else if (a[left] > a[right]){return left;}else{return right;}}
}

2.小區間優化

由于快速排序要遞歸數據區間,只要遞歸就要消耗空間,那么當數據區間比較小時,可以用插入排序,不用在遞歸了

//小區間排序 -> 插入排序
if ((right - left + 1) < 10)
{//注意數組取的位置和數組的長度InsertSort(a+left, right - left + 1);
}

快速排序有三種排序方法:

hoare

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
此時,數據6已經排好了,只需要遞歸它的左邊與右邊進行排序即可

// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{//三數取中int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int begin = left;int end = right;while (begin < end){while (begin < end && a[end] >= a[keyi]){end--;}while (begin < end && a[begin] <= a[keyi]){begin++;}Swap(&a[begin], &a[end]);}Swap(&a[keyi], &a[begin]);return begin;
}

挖坑法

在這里插入圖片描述
在這里插入圖片描述

// 快速排序挖坑法
int PartSort2(int* a, int left, int right)
{//三數取中int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);int key = a[left];int begin = left;int end = right;while (begin < end){while (begin < end && a[end] >= key){end--;}a[begin] = a[end];while (begin < end && a[begin] <= key){begin++;}a[end] = a[begin];}a[begin] = key;return begin;
}

前后指針

在這里插入圖片描述
在這里插入圖片描述

// 快速排序前后指針法
int PartSort3(int* a, int left, int right)
{//三數取中int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int prev = left;int cur = prev + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur){Swap(&a[cur], &a[prev]);}cur++;}Swap(&a[prev], &a[keyi]);return prev;
}

快排遞歸實現:

以上三種方法針對的是每一次排序,我們還需要遞歸剩下的區間來完成數據的有效

void QuickSort(int* a, int left, int right)
{//[left,right]是閉區間if (left >= right){return;}//小區間排序 -> 插入排序if ((right - left + 1) < 10){//注意數組取的位置和數組的長度InsertSort(a+left, right - left + 1);}else{//隨便選擇一種排序方法即可int keyi = PartSort3(a,left,right);//[left,keyi-1] keyi [keyi+1,right]//遞歸左邊與右邊QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);}
}

在十萬個數據下面,快速排序遞歸方法走了7ms,在一百萬數據下面,走了80ms,可見效率非常快

在這里插入圖片描述

在這里插入圖片描述

快排非遞歸實現:

眾所周知,遞歸會在棧上開辟空間,當遞歸的深度很大時,會導致棧溢出,這時我們可以把快速排序改成用非遞歸的形式實現

遞歸改為非遞歸的方法有兩種:

  1. 用循環實現
  2. 利用棧來實現

現在我們利用棧來實現,這里的棧是數據結構里面的棧。因為內存的棧的空間很小,而堆的空間很大,數據結構的棧就是在堆上開辟的

在這里插入圖片描述

// 快速排序 非遞歸實現 
//利用棧來實現
void QuickSortNonR(int* a, 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);int keyi = PartSort3(a, begin, end);//[begin,keyi-1] keyi [keyi+1,end]if (keyi + 1 < end){STPush(&st, end);STPush(&st, keyi + 1);}if (begin < keyi - 1){STPush(&st, keyi - 1);STPush(&st, begin);}}STDestroy(&st);
}

在十萬個數據下面,快速排序非遞歸方法走了19ms,在一百萬數據下面,走了283ms,可見效率與遞歸方法的差不多

在這里插入圖片描述
在這里插入圖片描述

七、歸并排序

歸并排序的時間復雜度是O(NlongN),空間復雜度是O(N),具有穩定性

在這里插入圖片描述

歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide
andConquer)的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表,稱為二路歸并。

歸并排序核心步驟:
將數據劃分區間,區間大小從小到大,每個區間進行歸并,歸并完成后就要拷貝回去

在這里插入圖片描述

歸并遞歸實現:

void _MergeSort(int* a, int* tmp, int left,int right)
{//遞歸if (left >= right){return;}int mid = (left + right) / 2;//[left,mid][mid+1,right]_MergeSort(a, tmp, left, mid);_MergeSort(a, tmp, mid+1, right);//歸并int begin1 = left;int end1 = mid;int begin2 = mid + 1;int end2 = right;int i = left;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];}}while (begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}//拷貝memcpy(a + left, tmp + left, (right - left + 1) * sizeof(int));
}//歸并排序
void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(n * sizeof(int));if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, tmp, 0, n - 1);free(tmp);tmp = NULL;
}

在十萬個數據下面,歸并排序遞歸方法走了9ms,在一百萬數據下面,走了93ms,可見效率非常快
在這里插入圖片描述
在這里插入圖片描述

歸并非遞歸實現:

上面我們提到遞歸會有棧溢出的問題,所有我們可以嘗試一下歸并的非遞歸的實現方法

遞歸改為非遞歸的方法有兩種:

  1. 用循環實現
  2. 利用棧來實現

這次我們使用循環來實現,歸并的核心就是分區間進行排序,既然如此, 我們可以設置分組gap的初始值為1,然后歸并一次,歸并完成后gap乘以2,來進行下一次的歸并區間,不斷重復此步驟直到gap 大于等于 數組長度時退出循環

//歸并排序 非遞歸實現
void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}//分組排序 每次兩個gap組進行歸并排序int gap = 1;while (gap < n){for (int i = 0; i < n; i+=2*gap){int begin1 = i;int end1 = i + gap - 1;int begin2 = i + gap;int end2 = i + 2 * gap - 1;int j = i;//printf("[%d,%d],[%d,%d]", begin1, end1, begin2, end2);//如果begin2越界了,就不歸并if (begin2 >= n){break;}//如果end2越界了,就修正if (end2 >= n){end2 = n - 1;}//歸并排序while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[j++] = a[begin1++];}else{tmp[j++] = a[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));}gap *= 2;}free(tmp);tmp = NULL;
}

在十萬個數據下面,歸并排序非遞歸方法走了9ms,在一百萬數據下面,走了87ms,可見效率非常快

在這里插入圖片描述
在這里插入圖片描述

八、各個排序的對比圖

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/37052.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/37052.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/37052.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uni-app 微信小程序開發到發布流程

1. uni-app 微信小程序開發到發布流程 1.1. 新建一個uni-app 項目 1.2. 發行微信小程序 1.3. 微信開發者平臺的微信小程序appid 復制進來&#xff08;點擊發行&#xff09; 1.4. IDE may already started at port xxxx, trying to connect &#xff08;1&#xff09;關閉微信…

小白上手AIGC-基于FC部署stable-diffusion

AIGC AIGC&#xff08;人工智能創造內容&#xff09;作為一種基于人工智能技術生成內容的新型創作模式。打破了過去大家對于AI的理解都是說只能涉足部分領域而無法涉足藝術或者是其他的創作領域的定律&#xff0c;現在的AIGC也能夠創作內容了&#xff0c;而不再只是單純的返回…

動手學深度學習(Pytorch版)代碼實踐 -計算機視覺-45多尺度目標檢測

45多尺度目標檢測 # 多尺度錨框 """ 減少圖像上的錨框數量并不困難。 比如&#xff0c;我們可以在輸入圖像中均勻采樣一小部分像素&#xff0c; 并以它們為中心生成錨框。 此外&#xff0c;在不同尺度下&#xff0c;我們可以生成不同數量和不同大小的錨框。 直…

Apifox 更新|定時任務、內網自部署服務器運行接口定時導入、數據庫 SSH 隧道連接

Apifox 新版本上線啦&#xff01; 看看本次版本更新主要涵蓋的重點內容&#xff0c;有沒有你所關注的功能特性&#xff1a; 自動化測試支持設置「定時任務」支持內網自部署服務器運行「定時導入」數據庫均支持通過 SSH 隧道連接自動化測試數據庫操作優化 1、自動化測試支持設…

C++ 100 之 容器插入和刪除

vector插入和刪除操作 insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count個元素ele. push_back(ele); //尾部插入元素ele pop_back();//刪除最后一個元素 erase(const_iterator start, const_iterator end);//刪除迭代器從start到end之間的元素 erase(c…

Mac(M1芯片)安裝多個jdk,Mac卸載jdk

1.jdk下載 oracle官方鏈接&#xff1a;oracle官方下載鏈接 2.安裝 直接下一步&#xff0c;下一步就行 3.查看是否安裝成功 出現下圖內容表示安裝成功。 4.配置環境變量 open -e .bash_profile 路徑建議復制過去 #刷新環境變量 source ~/.bash_profile 5.切換方法 6.jdk…

企業應該如果安全上網,軟件防查盜版,企業防盜版

隨著信息化的發展&#xff0c;企業日常辦公越來越依賴互聯網。終端以及普通PC終端在訪問互聯網過程中&#xff0c;會遇到各種各樣不容忽視的風險&#xff0c;例如員工主動故意的數據泄漏&#xff0c;后臺應用程序偷偷向外部發信息&#xff0c;木馬間諜軟件的外聯&#xff0c;以…

Spring Boot 過濾器和攔截器詳解

目錄 Spring Boot 過濾器1.什么是過濾器2.工作機制3.實現過濾器 Spring Boot 攔截器1. 什么是攔截器2. 工作原理3.實現4.拓展&#xff08;MethodInterceptor 攔截器&#xff09;實現 過濾器和攔截器區別過濾器和攔截器應用場景過濾器攔截器 Spring Boot 過濾器 1.什么是過濾器 …

信創認證 | Smartbi Insight V11成功適配申威3231處理器

在信息技術飛速發展的浪潮中&#xff0c;軟硬件的深度融合與協同發展已成為推動行業創新的關鍵因素。 近日&#xff0c;思邁特商業智能與數據分析軟件[簡稱&#xff1a;Smartbi Insight]V11在統信服務器操作系統V20和中電科申泰信息科技有限公司產品申威3231處理器環境下完成適…

日本職場跳槽漲薪調查報告!原來薪資漲幅的秘訣在這!

看到篇帖子&#xff0c;日本職場跳槽的調查報告&#xff1a; 文章中根據日本大型求職網站doda&#xff0c;通過分析網站注冊會員的數據以及職業顧問的解說&#xff0c;來了解一下跳槽實現工資提升的人基本情況以及趨勢。 本次調查對象跳槽后平均年收入提升了906,274日元&#…

Python 語法基礎一

1.變量 python 中變量很簡單&#xff0c;不需要指定數據類型&#xff0c;直接使用等號定義就好。python變量里面存的是內存地址&#xff0c;也就是這個值存在內存里面的哪個地方&#xff0c;如果再把這個變量賦值給另一個變量&#xff0c;新的變量通過之前那個變量知道那個變量…

《昇思25天學習打卡營第10天 | 昇思MindSporeFCN圖像語義分割》

第10天 本節學習了FCN圖像語義分割。全卷積網絡是用于圖像語義分割的一種框架。FCN是首個端到端&#xff08;end to end&#xff09;進行像素級&#xff08;pixel level&#xff09;預測的全卷積網絡。FCN有兩大明顯的優點&#xff1a;一是可以接受任意大小的輸入圖像&#xff…

【滲透工具】內網多級代理工具Venom詳細使用教程

免責申明 本公眾號的技術文章僅供參考&#xff0c;此文所提供的信息只為網絡安全人員對自己所負責的網站、服務器等&#xff08;包括但不限于&#xff09;進行檢測或維護參考&#xff0c;未經授權請勿利用文章中的技術資料對任何計算機系統進行入侵操作。利用此文所提供的信息…

【LeetCode】九、雙指針算法:環形鏈表檢測 + 救生艇

文章目錄 1、雙指針算法1.1 對撞雙指針1.2 快慢雙指針 2、leetcode141&#xff1a;環形鏈表3、leetcode881&#xff1a;救生艇 1、雙指針算法 用兩個指針來共同解決一個問題&#xff1a; 1.1 對撞雙指針 比如先有一個有序的數組array int[] array {1, 4, 5, 7, 9}先要找兩個…

什么是產線工控安全,如何保障產線設備的安全

什么是產線工控安全&#xff1f; 工控&#xff0c;指的是工業自動化控制&#xff0c;主要利用電子電氣、機械、軟件組合實現。即是工業控制系統&#xff0c;或者是工廠自動化控制。產線工控安全指的是工業控制系統的數據、網絡和系統安全。隨著工業信息化的迅猛發展&#xff0…

如何利用“AI交互數字人+展廳”拓展文娛消費空間?

打造新生代潮玩聚集地&#xff0c;打造演藝新空間&#xff0c;促進虛擬現實體驗等文娛業態場景創新&#xff0c;成為了當下發展文旅消費新場景的一大重要手段。數字人匯集了虛擬現實、增強現實、全息投影、人工智能、實時傳輸語音合成等數字技術&#xff0c;可以利用數字人重構…

SpringBoot項目中獲取IP地址

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言 OkHttp 是一個由 Square 開發的高效、現代的 HTTP 客戶端庫&#xff0c;用于 Android 和 Java 應用程序。它支持 HTTP/2 和 SPDY 等現代網絡協議&#xff0c;…

Jmeter 進行http接口測試

&#x1f345; 視頻學習&#xff1a;文末有免費的配套視頻可觀看 &#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 本文主要針對http接口進行測試&#xff0c;使用 jmeter工具實現。 Jmeter工具設計之初是用于做性…

如何用Vue3和Plotly.js繪制動態3D圖表?

本文由ScriptEcho平臺提供技術支持 項目地址&#xff1a;傳送門 Plotly.js: 使用Vue.js動態加載數據并繪制圖表 應用場景 在數據可視化應用中&#xff0c;需要將數據動態加載到圖表中并進行實時更新。本文將展示如何使用Plotly.js和Vue.js實現這一功能&#xff0c;從加載外…

MobPush iOS端海外推送最佳實現

推送注冊 在AppDelegate里進行SDK初始化&#xff08;也可以在Info.plist文件中進行AppKey&#xff0c;AppSecret的配置&#xff09;并對通知功能進行注冊以及設置推送的環境和切換海外服務器等&#xff0c;參考如下步驟代碼&#xff1a; <span style"background-colo…