1.選擇排序(Selection Sort):
選擇最小元素,移動(dòng)到首位置。
(1)算法描述和實(shí)現(xiàn):
- 首先選擇數(shù)組中最小的元素,然后與數(shù)組的第一個(gè)元素交換;
- 再?gòu)氖O碌臄?shù)據(jù)選擇最小的元素,與數(shù)組的第二個(gè)元素交換;
- 如此往復(fù),直到整個(gè)數(shù)組排序;
template <class E>
void selectSort(E *arr,int n)
{
for(int i=0;i<n;i++)
{
int minIndex=i;
for(int j=i+1;j<n;j++)
{
if(arr[j]<arr[minIndex])
{
minIndex=j;
}
}
if(minIndex!=i) swap(arr[i],arr[minIndex]);
}
}
(2)選擇排序動(dòng)圖演示:
(3)算法分析
時(shí)間復(fù)雜度:
- 最好情況:Θ(n2)
- 最差情況:Θ(n2)
- 平均情況 :Θ(n2)
輔佐空間:
- 無
2.冒泡排序(Bubble Sort)
對(duì)相鄰元素進(jìn)行比較調(diào)整的排序算法。它重復(fù)地走過排序的數(shù)列,比較相鄰元素,如果他們的順序錯(cuò)誤就把他們交換過來。如果沒有錯(cuò)誤的順序,說明數(shù)列已經(jīng)排序完成。這個(gè)算法名字的由來是因?yàn)檎麄€(gè)過程就像燒開水一樣,較小值像水中的氣泡一樣往上冒,而每一趟都有一個(gè)最大的元素沉底。
(1)算法描述和實(shí)現(xiàn):
- <1>.比較相鄰的元素,如果第一個(gè)比第二個(gè)大,兩者交換。
- <2>.對(duì)每一對(duì)相鄰元素做同樣的工作,從最開始的一對(duì)到最后一對(duì)。這樣,最后一個(gè)元素就是當(dāng)前序列的最大值。
- <3>.如果中途發(fā)現(xiàn)無逆序元素,則排序結(jié)束;否則當(dāng)只剩下兩個(gè)元素沒排時(shí),排完這一趟就結(jié)束。
無優(yōu)化
template <class E>
void bubbleSort(E *arr,int n)
{
for(int i=1;i<n;i++)//需要排n-1趟
{
for(int j=0;j<n-i;j++)
{
if(arr[j]>arr[j+1]) swap(arr[j],arr[j+1]);
}
}
}
改進(jìn)冒泡排序 1:設(shè)置一個(gè)標(biāo)志work,如果沒有逆序?qū)Γ瑒t說明序列已經(jīng)有序,算法結(jié)束。
template <class E>
void bubbleSort(E *arr,int n)
{
int work;
for(int i=1;i<n;i++)//需要排n-1趟
{
work=0;
for(int j=0;j<n-i;j++)
{
if(arr[j]>arr[j+1])
{
swap(arr[j],arr[j+1]);
work=1;
}
}
if(!work) break;
}
}
改進(jìn)冒泡排序 2:設(shè)置標(biāo)志位pos,用以記錄最后一次進(jìn)行交換的位置。由于pos之后的記錄都已經(jīng)交換到位,故在下一趟排序時(shí)只需要掃描到pos位置即可。
template <class E>
void bubbleSort(E *arr,int n)
{
int pos,i=n-1;
while(i>0)
{
pos=0;//每趟開始時(shí),無交換記錄
for(int j=0;j<i;j++)
{
if(arr[j]>arr[j+1])
{
swap(arr[j],arr[j+1]);
pos=j;//記錄交換的位置
}
}
i=pos;//為下一趟做準(zhǔn)備
}
}
改進(jìn)冒泡排序 3:傳統(tǒng)冒泡排序中每一趟排序操作只能找到一個(gè)最大值或最小值,我們考慮利用在每趟排序中進(jìn)行正向和反向兩遍冒泡的方法一次可以得到兩個(gè)最終值(最大者和最小者) , 從而使排序趟數(shù)幾乎減少了一半。
template <class E>
void bubbleSort(E *arr,int n)
{
int low=0,high=n-1;
while(low<high)
{
for(int i=low;i<high;i++) //正向冒泡,找到最大值
{
if(arr[i]>arr[i+1]) swap(arr[i],arr[i+1]);
}
--high; //修改high值,前移一位
for(int j=high;j>low;j--) //反向冒泡,找到最小值
{
if(arr[j]<arr[j-1]) swap(arr[j],arr[j-1]);
}
++low; //修改low值,后移一位
}
}
(2)冒泡排序動(dòng)圖演示:
( 3 )算法分析
時(shí)間復(fù)雜度:
- 最佳情況:Θ(n)(當(dāng)輸入數(shù)據(jù)為正序時(shí))
- 最壞情況:Θ(n2)(當(dāng)輸入數(shù)據(jù)為反序時(shí))
- 平均情況:Θ(n2)
輔佐空間:
- 無
3.插入排序(Insertion Sort )
通常人們整理牌的方法是將每一張牌插入到其他有序的牌中的合適位置,插入排序與此類似。
( 1 )算法描述和實(shí)現(xiàn)
- <1>.從第一個(gè)元素開始,該元素可以認(rèn)為已經(jīng)被排序;
- <2>.取出下一個(gè)元素,在已經(jīng)排序的元素序列中從后向前掃描;
- <3>.如果該元素(已排序)大于新元素,將該元素移到下一位置;
- <4>.重復(fù)步驟3,直到找到已排序的元素小于或者等于新元素的位置;
- <5>.將新元素插入到該位置后;
- <6>.重復(fù)步驟2~5。
template <class E>
void insertSort(E *arr,int n)
{
for(int i=1;i<n;i++)
{
E key=arr[i];
int j=i-1;
while(j>=0&&arr[j]>key)
{
arr[j+1]=arr[j];
j--;
}
arr[j+1]=key;
}
}
改進(jìn)插入排序:查找合適位置時(shí)使用二分查找,這樣移動(dòng)元素就不需要一個(gè)個(gè)判斷大小關(guān)系了。二分查找
template <class E>
void insertSort(E *arr,int n)
{
for(int i=1;i<n;i++)
{
E key=arr[i];
int lef=0,rig=i,mid;
while(lef<rig)//查找key的上界,即查找第一個(gè)大于key的元素,沒找到則lef=i
{
mid=(lef+rig)/2;
if(arr[mid]<=key)
{
lef=mid+1;
}
else rig=mid;
}
int j=i-1;
while(j>=lef)
{
arr[j+1]=arr[j];
j--;
}
arr[lef]=key;
}
}
插入排序動(dòng)圖演示:
(3)算法分析
時(shí)間復(fù)雜度
- 最佳情況:輸入數(shù)組按升序排列。T(n) = Θ(n)
- 最壞情況:輸入數(shù)組按降序排列。T(n) = Θ(n2)
- 平均情況:T(n) = Θ(n2)
輔佐空間:
- 無
4.希爾排序( Shell Sort)
第一個(gè)突破O(n^2)的排序算法;是簡(jiǎn)單插入排序的改進(jìn)版;它與插入排序的不同之處在于,它會(huì)優(yōu)先比較距離較遠(yuǎn)的元素。希爾排序又叫縮小增量排序。希爾排序的核心在于間隔序列的設(shè)定。
(1)算法描述和實(shí)現(xiàn)
- <1>.選擇一個(gè)增量序列t1,t2,...tk;其中,tk=1;
- <2>.按增量序列個(gè)數(shù)k,對(duì)序列進(jìn)行k 趟排序;
- <3>.每趟排序,根據(jù)對(duì)應(yīng)的增量ti,將待排序列分割成若干長(zhǎng)度為m 的子序列,分別對(duì)各子表進(jìn)行直接插入排序。僅增量因子為1 時(shí),整個(gè)序列作為一個(gè)表來處理,表長(zhǎng)度即為整個(gè)序列的長(zhǎng)度。
template <class E>
void shellSort(E *arr,int n)
{
int h=1;
while(h<n/3) h=3*h+1;
while(h>=1)
{
for(int i=h;i<n;i++)
{
E key=arr[i];
int j=i-h;
while(j>=0&&arr[j]>key)
{
arr[j+h]=arr[j];
j-=h;
}
arr[j+h]=key;
}
h/=3;
}
}
希爾排序圖示(圖片來源網(wǎng)絡(luò)):
(2)算法分析:
時(shí)間復(fù)雜度
- 最佳情況:T(n) = Θ(n^(1+c1))
- 最壞情況:T(n) = Θ(n^(1+c2))
- 平均情況:T(n) =Θ(n^(1+c3))
輔佐空間:
- 無
5.歸并排序(Merge Sort)
和選擇排序一樣,歸并排序的性能不受輸入數(shù)據(jù)的影響,但表現(xiàn)比選擇排序好的多,因?yàn)槭冀K都是O(n log n)的時(shí)間復(fù)雜度。代價(jià)是需要額外的內(nèi)存空間。歸并排序是建立在歸并操作上的一種有效的排序算法。該算法是采用分治法(Divide and Conquer)的一個(gè)非常典型的應(yīng)用。歸并排序是一種穩(wěn)定的排序方法。將已有序的子序列合并,得到完全有序的序列;即先使每個(gè)子序列有序,再使子序列段間有序。若將兩個(gè)有序表合并成一個(gè)有序表,稱為2-路歸并。
( 1 )算法描述和實(shí)現(xiàn)
- <1>.把長(zhǎng)度為n的輸入序列分成兩個(gè)長(zhǎng)度為n/2的子序列;
- <2>.對(duì)這兩個(gè)子序列分別采用歸并排序;
- <3>.將兩個(gè)排序好的子序列合并成一個(gè)最終的排序序列。
template <class E>
void merge(E *arr,E *aux,int lef,int mid,int rig)
{
int i=lef,j=mid+1,k;
for(k=lef;k<=rig;k++)
{
aux[k]=arr[k];
}
k=lef;
while(i<=mid&&j<=rig)
{
/*
if(aux[i]<aux[j]) arr[k++]=aux[i++];//非穩(wěn)定排序
else arr[k++]=aux[j++];
*/
if(aux[i]<=aux[j]) arr[k++]=aux[i++];//穩(wěn)定排序
else arr[k++]=aux[j++];
}
if(i>mid)
{
while(j<=rig)
{
arr[k++]=aux[j++];
}
}
if(j>rig)
{
while(i<=mid)
{
arr[k++]=aux[i++];
}
}
}
template<class E>
void mergeSort(E *arr,E *aux,int lef,int rig)
{
if(rig<=lef) return;//區(qū)間長(zhǎng)度小于等于1,不需要合并
int mid=(lef+rig)/2;
mergeSort(arr,aux,lef,mid);
mergeSort(arr,aux,mid+1,rig);
merge(arr,aux,lef,mid,rig);
}
template <class E>
void mergeSort(E *arr,int n)
{
E *aux=new E[n];
mergeSort(arr,aux,0,n-1);
}
歸并排序動(dòng)圖演示:
(3)算法分析
時(shí)間復(fù)雜度:
- 最佳情況:T(n) = Θ(nlogn)
- 最差情況:T(n) = Θ(nlogn)
- 平均情況:T(n) = Θ(nlogn)
輔佐空間:
- Θ(n)
6.快速排序(Quick Sort)
快速排序的基本思想:通過一趟排序?qū)⒋庞涗浄指舫瑟?dú)立的兩部分,其中一部分記錄的關(guān)鍵字均比另一部分的關(guān)鍵字小,則可分別對(duì)這兩部分記錄繼續(xù)進(jìn)行排序,以達(dá)到整個(gè)序列有序。
(2)算法描述和實(shí)現(xiàn)
快速排序使用分治法來把一個(gè)串(list)分為兩個(gè)子串(sub-lists)。
具體算法描述如下:
- <1>.從數(shù)列中挑出一個(gè)元素,稱為 "基準(zhǔn)"(pivot);
- <2>.重新排序數(shù)列,所有元素比基準(zhǔn)值小的擺放在基準(zhǔn)前面,所有元素比基準(zhǔn)值大的擺在基準(zhǔn)的后面(相同的數(shù)可以到任一邊)。在這個(gè)分區(qū)退出之后,該基準(zhǔn)就處于數(shù)列的中間位置。這個(gè)稱為分區(qū)(partition)操作;
- <3>.遞歸地(recursive)把小于基準(zhǔn)值元素的子數(shù)列和大于基準(zhǔn)值元素的子數(shù)列排序。
首位置劃分
template <class E>
int partition(E *arr,int lef,int rig)
{
int i=lef,j=rig+1;
E x=arr[lef];
while(true)
{
while(arr[++i]<x&&i<rig);
while(arr[--j]>x);
if(i>=j) break;
swap(arr[i],arr[j]);
}
arr[lef]=arr[j];
arr[j]=x;
return j;
}
template <class E>
void quickSort(E *arr,int lef,int rig)
{
if(lef<rig)
{
int q=partition(arr,lef,rig);
quickSort(arr,lef,q-1);
quickSort(arr,q+1,rig);
}
}
template <class E>
void quickSort(E *arr,int n)
{
quickSort(arr,0,n-1);
}
隨機(jī)劃分:先隨機(jī)找一個(gè)劃分點(diǎn),然后把這個(gè)劃分點(diǎn)與首位置交換,則其他的代碼與上面的一樣。
template <class E>
int partition(E *arr,int lef,int rig)
{
int i=lef,j=rig+1;
int q=rand()%(rig-lef+1)+lef;
swap(arr[lef],arr[q]);
E x=arr[lef];
while(true)
{
while(arr[++i]<x&&i<rig);
while(arr[--j]>x);
if(i>=j) break;
swap(arr[i],arr[j]);
}
arr[lef]=arr[j];
arr[j]=x;
return j;
}
template <class E>
void quickSort(E *arr,int lef,int rig)
{
if(lef<rig)
{
int q=partition(arr,lef,rig);
quickSort(arr,lef,q-1);
quickSort(arr,q+1,rig);
}
}
template <class E>
void quickSort(E *arr,int n)
{
srand(int(time(0)));
quickSort(arr,0,n-1);
}
快速排序動(dòng)圖演示:
( 2 )算法分析
時(shí)間復(fù)雜度:
- 最佳情況:T(n) = Θ(nlogn)
- 最差情況:T(n) = Θ(n2)
- 平均情況:T(n) = Θ(nlogn)
輔佐空間:
- 無
7.堆排序(Heap Sort)
堆排序(Heapsort)是指利用堆這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法。堆積是一個(gè)近似完全二叉樹的結(jié)構(gòu),并同時(shí)滿足堆積的性質(zhì):即子結(jié)點(diǎn)的鍵值或索引總是小于(或者大于)它的父節(jié)點(diǎn)。
( 2 )算法描述和實(shí)現(xiàn)
具體算法描述如下:
- <1>.將初始待排序關(guān)鍵字序列(R1,R2....Rn)構(gòu)建成大頂堆,此堆為初始的無序區(qū);
- <2>.將堆頂元素R[1]與最后一個(gè)元素R[n]交換,此時(shí)得到新的無序區(qū)(R1,R2,......Rn-1)和新的有序區(qū)(Rn),且滿足R[1,2...n-1]<=R[n];
- <3>.由于交換后新的堆頂R[1]可能違反堆的性質(zhì),因此需要對(duì)當(dāng)前無序區(qū)(R1,R2,......Rn-1)調(diào)整為新堆,然后再次將R[1]與無序區(qū)最后一個(gè)元素交換,得到新的無序區(qū)(R1,R2....Rn-2)和新的有序區(qū)(Rn-1,Rn)。不斷重復(fù)此過程直到有序區(qū)的元素個(gè)數(shù)為n-1,則整個(gè)排序過程完成。
template <class E>
void sink(E *arr,int k,int n)
{
int j;
while(2*k+1<n)
{
j=2*k+1;
if(j<n-1&&arr[j]<arr[j+1]) j++;
if(arr[k]>=arr[j]) break;
swap(arr[k],arr[j]);
k=j;
}
}
template <class E>
void heapSort(E *arr,int n)
{
for(int i=(n-1)/2;i>=0;i--)//構(gòu)建堆
{
sink(arr,i,n);
}
while(n>1)//堆排序
{
swap(arr[0],arr[--n]);
sink(arr,0,n);
}
}
堆排序動(dòng)圖演示:
( 2 )算法分析
時(shí)間復(fù)雜度:
- 最佳情況:T(n) = O(nlogn)
- 最差情況:T(n) = O(nlogn)
- 平均情況:T(n) = O(nlogn)
輔佐空間:
- 無
8.計(jì)數(shù)排序(Counting Sort)
計(jì)數(shù)排序的核心在于將輸入的數(shù)據(jù)值轉(zhuǎn)化為鍵存儲(chǔ)在額外開辟的數(shù)組空間中。
作為一種線性時(shí)間復(fù)雜度的排序,計(jì)數(shù)排序要求輸入的數(shù)據(jù)必須是有確定范圍的整數(shù)。
(1)算法簡(jiǎn)介
計(jì)數(shù)排序(Counting sort)是一種穩(wěn)定的排序算法。計(jì)數(shù)排序使用一個(gè)額外的數(shù)組C,其中第i個(gè)元素是待排序數(shù)組A中值等于i的元素的個(gè)數(shù)。然后根據(jù)數(shù)組C來將A中的元素排到正確的位置。它只能對(duì)整數(shù)進(jìn)行排序。
(2)算法描述和實(shí)現(xiàn)
具體算法描述如下:
- <1>. 找出待排序的數(shù)組中最大和最小的元素;
- <2>. 統(tǒng)計(jì)數(shù)組中每個(gè)值為i的元素出現(xiàn)的次數(shù),存入數(shù)組C的第i項(xiàng);
- <3>. 對(duì)所有的計(jì)數(shù)累加(從C中的第一個(gè)元素開始,每一項(xiàng)和前一項(xiàng)相加);
- <4>. 反向填充目標(biāo)數(shù)組:將每個(gè)元素i放在新數(shù)組的第C(i)項(xiàng),每放一個(gè)元素就將C(i)減去1。
void countingSort(int *unSort,int *sorted,int n)//假設(shè)arr元素的最大值是1000
{
int c[1000];
int minVal=0x3f3f3f,maxVal=-0x3f3f3f;
memset(c,0,sizeof(c));
for(int i=0;i<n;i++)
{
c[unSort[i]]++;
minVal=minVal>unSort[i]?unSort[i]:minVal;
maxVal=maxVal<unSort[i]?unSort[i]:maxVal;
}
for(int i=minVal;i<maxVal;i++)
{
c[i+1]=c[i+1]+c[i];
}
for(int i=0;i<n;i++)
{
int index=c[unSort[i]]-1;
sorted[index]=unSort[i];
c[unSort[i]]--;
}
}
基數(shù)排序動(dòng)圖演示:
(3)算法分析
當(dāng)輸入的元素是n 個(gè)0到k之間的整數(shù)時(shí),它的運(yùn)行時(shí)間是 O(n + k)。計(jì)數(shù)排序不是比較排序,排序的速度快于任何比較排序算法。由于用來計(jì)數(shù)的數(shù)組C的長(zhǎng)度取決于待排序數(shù)組中數(shù)據(jù)的范圍(等于待排序數(shù)組的最大值與最小值的差加上1),這使得計(jì)數(shù)排序?qū)τ跀?shù)據(jù)范圍很大的數(shù)組,需要大量時(shí)間和內(nèi)存。
時(shí)間復(fù)雜度:
- 最佳情況:T(n) = O(n+k)
- 最差情況:T(n) = O(n+k)
- 平均情況:T(n) = O(n+k)
輔佐空間:
- 需要用一個(gè)數(shù)組c來記錄元數(shù)組元素出現(xiàn)的次數(shù),原數(shù)組的元素值對(duì)應(yīng)c數(shù)組的索引值,所以c的大小取決于原數(shù)組的數(shù)據(jù)范圍。
9.桶排序(Bucket Sort)
桶排序是計(jì)數(shù)排序的升級(jí)版。它利用了函數(shù)的映射關(guān)系,高效與否的關(guān)鍵就在于這個(gè)映射函數(shù)的確定。
(1)算法簡(jiǎn)介
桶排序 (Bucket sort)的工作的原理:假設(shè)輸入數(shù)據(jù)服從均勻分布,將數(shù)據(jù)分到有限數(shù)量的桶里,每個(gè)桶再分別排序(有可能再使用別的排序算法或是以遞歸方式繼續(xù)使用桶排序進(jìn)行排
(2)算法描述和實(shí)現(xiàn)
具體算法描述如下:
- <1>.設(shè)置一個(gè)定量的數(shù)組當(dāng)作空桶;
- <2>.遍歷輸入數(shù)據(jù),并且把數(shù)據(jù)一個(gè)一個(gè)放到對(duì)應(yīng)的桶里去;
- <3>.對(duì)每個(gè)不是空的桶進(jìn)行排序;
- <4>.從不是空的桶里把排好序的數(shù)據(jù)拼接起來。
template <class E>
void bucketSort(E *arr,int n,int bucketCount)
{
E minval=arr[0],maxval=arr[0];
for(int i=1;i<n;i++) //找到最大值和最小值
{
minval=minval>arr[i]?arr[i]:minval;
maxval=maxval<arr[i]?arr[i]:maxval;
}
//求出每一個(gè)桶的數(shù)值范圍
double space=(maxval-minval+1)*1.0/bucketCount;//這里必須用double值
//先創(chuàng)建好每一個(gè)桶的空間
vector<E> *bucket=new vector<E> [bucketCount];
for(int i=0;i<n;i++)
{
int index=(int)((arr[i]-minval)/space);
if(bucket[index].size()==0) //如果桶里里沒有東西,直接放進(jìn)去
{
bucket[index].push_back(arr[i]);
}
else //否則,進(jìn)行插入排序
{
int j=bucket[index].size()-1;
bucket[index].push_back(arr[i]);//先把數(shù)據(jù)加載進(jìn)桶,防止下面的bucket[index][j+1]出錯(cuò)
while(j>=0&&bucket[index][j]>arr[i])
{
bucket[index][j+1]=bucket[index][j];
j--;
}
bucket[index][j+1]=arr[i];
}
}
//把桶內(nèi)的結(jié)果合并
for(int i=0,index=0;i<bucketCount;i++)
{
for(int j=0;j<bucket[i].size();j++)
{
arr[index++]=bucket[i][j];
}
}
}
桶排序圖示(圖片來源網(wǎng)絡(luò)):
(3)算法分析
桶排序最好情況下使用線性時(shí)間O(n),桶排序的時(shí)間復(fù)雜度,取決與對(duì)各個(gè)桶之間數(shù)據(jù)進(jìn)行排序的時(shí)間復(fù)雜度,因?yàn)槠渌糠值臅r(shí)間復(fù)雜度都為O(n)。很顯然,桶劃分的越小,各個(gè)桶之間的數(shù)據(jù)越少,排序所用的時(shí)間也會(huì)越少。但相應(yīng)的空間消耗就會(huì)增大。
時(shí)間復(fù)雜度
- 最佳情況:T(n) = Θ(n+k)
- 最差情況:T(n) = Θ(n+k)
- 平均情況:T(n) = Θ(n2)
輔佐空間:
- Θ(n)
10.基數(shù)排序(Radix Sort)
基數(shù)排序也是非比較的排序算法,對(duì)每一位進(jìn)行排序,從最低位開始排序,復(fù)雜度為O(kn),為數(shù)組長(zhǎng)度,k為數(shù)組中的數(shù)的最大的位數(shù);
(1)算法簡(jiǎn)介
基數(shù)排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次類推,直到最高位。有時(shí)候有些屬性是有優(yōu)先級(jí)順序的,先按低優(yōu)先級(jí)排序,再按高優(yōu)先級(jí)排序。最后的次序就是高優(yōu)先級(jí)高的在前,高優(yōu)先級(jí)相同的低優(yōu)先級(jí)高的在前?;鶖?shù)排序基于分別排序,分別收集,所以是穩(wěn)定的。
(2)算法描述和實(shí)現(xiàn)
具體算法描述如下:
- <1>.取得數(shù)組中的最大數(shù),并取得位數(shù);
- <2>.arr為原始數(shù)組,從最低位開始取每個(gè)位組成radix數(shù)組;
- <3>.對(duì)radix進(jìn)行計(jì)數(shù)排序(利用計(jì)數(shù)排序適用于小范圍數(shù)的特點(diǎn));
int getDigit(int val,int k)
{
int arr[] = {1, 1, 10, 100,1000,10000,100000};
return (val/arr[k]) % 10;
}
void countingSort(int *arr,int *res,int n,int k)
{
int c[10];
memset(c,0,sizeof(c));
for(int i=0;i<n;i++)
{
c[getDigit(arr[i],k)]++;
}
for(int i=1;i<10;i++)
{
c[i]+=c[i-1];
}
for(int i=n-1;i>=0;i--)//為了保證準(zhǔn)確性,必須從高位開始排
{
int j=getDigit(arr[i],k);
res[c[j]-1]=arr[i];
c[j]--;
}
}
void radixSort(int *arr,int n,int maxDigit)
{
int *a1=arr,*a2=new int[n],*res;
for(int i=1;i<=maxDigit;i++)
{
countingSort(a1,a2,n,i);
res=a2;
swap(a1,a2);
}
for(int i=0;i<n;i++)
{
arr[i]=res[i];
}
}
基數(shù)排序LSD動(dòng)圖演示:
(3)算法分析
時(shí)間復(fù)雜度:
- 最佳情況:T(n) = Θ(n * k)
- 最差情況:T(n) = Θ(n * k)
- 平均情況:T(n) = Θ(n * k)
輔佐空間:
- Θ(n)