歸併排序:將兩個或兩個以上的有序表組合乙個新的有序表稱為「歸併」。先使每個子串行有序,再歸併使子串行段有序,最後得到完全有序的序列。
演算法思想:我們通常用遞迴實現,先把待排序區間[startindex,endindex]以中點二分,接著把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間[startindex,endindex]。
歸併過程:比較a[i]和b[j]的大小,若a[i]≤b[j],則將第乙個有序序列中的元素a[i]複製到r[k]中,並令i和k分別加上1;否則將第二個有序序列中的元素a[j]複製到r[k]中,並令j和k分別加上1,如此迴圈下去,直到其中乙個有序序列取完,然後再將另乙個有序序列中剩餘的元素複製到r中從下標k到下標endindex的單元。
如圖所示:
上半部分為2分法使資料為有序序列,下半部分為歸併有序序列操作,最後為完全有序。
示例**如下:(測試**自己寫)
c++ code 12
3456
78910
1112
1314
1516
1718
1920
2122
2324
2526
2728
2930
3132
3334
3536
3738
3940
4142
43void
merge(
int*arr,
int*tmp,
intstartindex,
intmidindex,
intendindex)//歸併操作
else
}while
(i != midindex + 1)
while
(j != endindex + 1)
for(
inti = startindex; i <= endindex; i++)
}void
guib(
int*arr,
int*tmp,
intstartindex,
intendindex)//歸併排序}
注:測試只需在main函式中建立兩個陣列,呼叫guib函式即可。
時間複雜度:一趟歸併排序呼叫n/2h次演算法merge將arr【1..n】中前後相鄰且長度為h的有序段兩兩合併得到2h的有序段,並存放到tmp【1..n】中。整個歸併排序需要log2^n趟。所以需要移動操作2*2h*(n/2h)*log2^n=2log2^n;比較操作是(n/2h)*h*log2^n=n/2log2^n;此演算法時間複雜度為nlgn.
空間複雜度:o(1)。
穩定性:每次歸併若元素相同,不改變前後順序,所以為穩定的。
續:非遞迴實現**
c++ code 12
3456
78910
1112
1314
1516
1718
1920
2122
2324
2526
2728
2930
3132
3334
3536
3738
3940
4142
4344
4546
4748
4950
5152
5354
5556
57#include
#include
void
mergesort(
int*arr,
int*tmp,
intlength)
while
(leftmin
1&& rightmin
while
(leftmin
while
(rightmin
for(
intj = leftmin; j <= rightmax; j++)}}
}#define
n 10
intmain()
;int
t[n];
mergesort(a, t, n);
for(
inti =
0; i
基數排序:又稱「桶排序」,通過鍵值的部分的資訊,將要排序的元素分配到某些「桶」中,以此達到排序的目的。
演算法思想:從最次位的關鍵字k^(d-1)起進行排序。然後再對高一位的關鍵字k^(d-2)進行排序,依次重複,直至對k^0進行排序後成為乙個有序序列。叫「最低位優先」,簡稱lsd法。
排序過程如圖所示:
**如下:
c++ code 12
3456
78910
1112
1314
1516
1718
1920
2122
2324
2526
2728
2930
3132
3334
3536
3738
3940
4142
4344
4546
4748
4950
5152
5354
//資料最大值的位數 即排序躺數 (543)3
intfindmaxfigure(
int*arr,
intlen)
}int
count = 0;
dowhile
(max != 0);
return
count;
}//資料的位上的數字 (45 0)1、(54 1)5
intfindnums(
intnum,
intfigure)
//根據資料每一位進行入桶和出桶操作
void
radix(
int*arr,
intlen,
intfigures)
;int
count[
10] = {};
for(
inti =
0; i
intk = 0;
for(
inti =
0; i
10; i++)}}
//基數排序(桶排序)
void
radixsort(
int*arr,
intlen)}
注:測試只需在main函式中呼叫void radixsort(int *arr, int len)就行。
時間複雜度: 可知排序躺數為count次,入桶和出桶操作為n,賦值給原始陣列為r*n,r為基數。所以時間複雜度為 o(n(count+r))。
空間複雜度:輔助儲存陣列tmp、count,所以為o(r*n+r),r為基數。
穩定性:穩定。
八大排序之基數排序
個人部落格 建議先看排序綜述,傳送門 資料結構與演算法系列之一 八大排序綜述。基數排序 英語 radix sort 是一種非比較型整數排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。由於整數也可以表達字串 比如名字或日期 和特定格式的浮點數,所以基數排序也不是只能使用於整數...
八大排序之基數排序
開始研究基數排序,還以為很複雜呢,誰知道也挺簡單的,它是一種非比較的排序,首先找到最大的位數,也就是先確定裡面最大的數有幾位,依次對個位,十位,等進行排序,它的原理就是你在對個位的大小進行排序時,算了,還是放圖吧 個位排序 它已經出現了基本有序 相對於十位來說 如,142,157,142也就在157...
八大排序 基數排序
基數排序 將整形10進製按每位拆分,然後從低位到高位依次比較各個位。每次比較完進行排序,直到整個陣列有序 主要分為兩個過程 1 分配,先從個位開始,根據位值 0 9 分別放到0 9號桶中 比如53,個位為3,則放入3號桶中 2 收集,再將放置在0 9號桶中的資料按順序放到陣列中 重複 1 2 過程,...