




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、1210.1 概述概述10.2 插入排序插入排序10.3 快速排序快速排序10.4 堆排序堆排序10.5 歸并排序歸并排序10.6 基數(shù)排序基數(shù)排序10.6 各種排序方法的綜合比較各種排序方法的綜合比較10.8 外部排序外部排序310.1 概概 述述一、排序的定義一、排序的定義二、內部排序和外部排序二、內部排序和外部排序三、內部排序方法的分類三、內部排序方法的分類4一、什么是排序?一、什么是排序?排序是計算機內經(jīng)常進行的一種操作,其目的是將一組“無序無序”的記錄序列調的記錄序列調整為整為“有序有序”的記錄序列。例如:將下列關鍵字序列52, 49, 80, 36, 14, 58, 61, 23,
2、 97, 75調整為14, 23, 36, 49, 52, 58, 61 ,75, 80, 975 一般情況下,假設含n個記錄的序列為 R1, R2, , Rn 其相應的關鍵字序列為 K1, K2, ,Kn 這些關鍵字相互之間可以進行比較,即在它們之間存在著這樣一個關系 Kp1Kp2Kpn按此固有關系將上式記錄序列重新排列為 Rp1, Rp2, ,Rpn 的操作操作稱作排序排序。6二、內部排序和外部排序二、內部排序和外部排序若整個排序過程不需要訪問外存不需要訪問外存便能完成,則稱此類排序問題為內部排內部排序序; 反之,若參加排序的記錄數(shù)量很大, 整個序列的排序過程不可能在內存中 完成,則稱此類
3、排序問題為外部排序外部排序。7三、內部排序的方法三、內部排序的方法內部排序的過程是一個逐步擴大逐步擴大記錄的有序序列長度有序序列長度的過程。經(jīng)過一趟排序經(jīng)過一趟排序有序序列區(qū)無 序 序 列 區(qū)有序序列區(qū)無 序 序 列 區(qū)8基于不同的“擴大擴大” 有序序列長度的方法,內部排序方法方法,內部排序方法大致可分下列幾種類型:插入類插入類交換類交換類選擇類選擇類 歸并類歸并類其它方法其它方法9待排記錄的數(shù)據(jù)類型定義如下待排記錄的數(shù)據(jù)類型定義如下:const MAXSIZE = 1000; / 待排順序表最大長度待排順序表最大長度typedef int KeyType; / 關鍵字類型為整數(shù)類型關鍵字類型
4、為整數(shù)類型typedef struct KeyType key; / 關鍵字項關鍵字項 InfoType otherinfo; / 其它數(shù)據(jù)項其它數(shù)據(jù)項 RcdType; / 記錄類型記錄類型typedef struct RcdType rMAXSIZE+1; / r0閑置閑置 int length; / 順序表長度順序表長度 SqList; / 順序表類型順序表類型10 10. 2 插插 入入 排排 序序11有序序列R1.i-1Ri無序序列 Ri.n一趟直接插入排序的基本思想:有序序列R1.i無序序列 Ri+1.n12實現(xiàn)實現(xiàn)“一趟插入排序一趟插入排序”可分三步進行:可分三步進行:3將Ri
5、插入插入(復制)到Rj+1的位置上。2將Rj+1.i-1中的所有記錄記錄均后移后移 一個位置;1在R1.i-1中查找查找Ri的插入位置 j ; R1.j.key Ri.key Rj+1.i-1.key13直接插入排序直接插入排序(基于順序查找)(基于順序查找)表插入排序表插入排序(基于鏈表存儲)(基于鏈表存儲)不同的具體實現(xiàn)方法導致不同的算法描述不同的具體實現(xiàn)方法導致不同的算法描述折半插入排序折半插入排序(基于折半查找)(基于折半查找)希爾排序希爾排序(基于逐趟縮小增量)(基于逐趟縮小增量)14一、直接插入排序一、直接插入排序利用 “順序查找順序查找”實現(xiàn)“在R1.i-1中查找查找Ri的插入位
6、置”算法的實現(xiàn)要點:算法的實現(xiàn)要點:15從Ri-1起向前進行順序查找, 監(jiān)視哨設置在R0;R0 = Ri; / 設置“哨兵”循環(huán)結束表明Ri的插入位置為 j +1R0jRifor (j=i-1; R0.keyRj.key; -j); / 從后往前找j=i-1插入位置插入位置16 對于在查找過程中找到的那些關鍵字不小于Ri.key的記錄,并在查找的同時實現(xiàn)記錄向后移動;for (j=i-1; R0.keyRj.key; -j); Rj+1 = RjR0jRij= i-1上述循環(huán)結束后可以直接進行“插入”插入位置插入位置17令 i = 2,3,, n, 實現(xiàn)整個序列的排序。for ( i=2; i
7、=n; +i ) if (Ri.keyRi-1.key) 在 R1.i-1中查找Ri的插入位置; 插入Ri ; 18void InsertionSort ( SqList &L ) / 對順序表 L 作直接插入排序。 for ( i=2; i=L.length; +i ) if (L.ri.key L.ri-1.key) /if / InsertSortL.r0 = L.ri; / 復制為監(jiān)視哨復制為監(jiān)視哨L.ri = L.ri-1;for ( j=i-2; L.r0.key L.rj.key; - j ) L.rj+1 = L.rj; / 記錄后移記錄后移L.rj+1 = L.r0;
8、 / 插入到正確位置插入到正確位置19內部排序的時間分析時間分析:實現(xiàn)內部排序的基本操作基本操作有兩個:(2)“移動移動”記錄。(1)“比較比較”序列中兩個關鍵字的 大?。?0對于直接插入排序:最好的情況(關鍵字在記錄序列中順序有序):最好的情況(關鍵字在記錄序列中順序有序):“比較”的次數(shù):最壞的情況(關鍵字在記錄序列中逆序有序):最壞的情況(關鍵字在記錄序列中逆序有序):“比較”的次數(shù):112nni02) 1)(4() 1(2nnini“移動”的次數(shù):“移動”的次數(shù):2)1(2nnini( )221 因為 R1.i-1 是一個按關鍵字有序的有序序列,則可以利用折半查找折半查找實現(xiàn)“在R1.
9、i-1中查找查找Ri的插入位置”,如此實現(xiàn)的插入排序為折半插折半插入入排序。二、折半插入排序二、折半插入排序22void BiInsertionSort ( SqList &L ) / BInsertSort在在 L.r1.i-1中折半查找插入位置;中折半查找插入位置;for ( i=2; i=high+1; -j ) L.rj+1 = L.rj; / 記錄后移L.rhigh+1 = L.r0; / 插入23low = 1; high = i-1;while (low=high) m = (low+high)/2; / 折半if (L.r0.key L.rm.key) high = m
10、-1; / 插入點在低半?yún)^(qū)else low = m+1; / 插入點在高半?yún)^(qū)24ilowhighmmlowlowmhighilowhighmhighmhighmlow例如:再如:插入位置插入位置14 36 49 52 80 58 61 23 97 75L.r14 36 49 52 58 61 80 23 97 75L.r25 四、希爾排序(又稱縮小增量排序)四、希爾排序(又稱縮小增量排序) 基本思想:對待排記錄序列先作“宏觀”調整,再作“微觀”調整。 所謂“宏觀”調整,指的是,“跳躍式”的插入排序。 具體做法為:26將記錄序列分成若干子序列,分別對每個子序列進行插入排序。其中,d 稱為增量,它
11、的值在排序過程中從大到小逐漸縮小,直至最后一趟排序減為 1。例如:將 n 個記錄分成 d 個子序列: R1,R1+d,R1+2d,R1+kd R2,R2+d,R2+2d,R2+kd Rd,R2d,R3d,Rkd,R(k+1)d 27例如:16 25 12 30 47 11 23 36 9 18 31 第一趟希爾排序,設增量 d =511 23 12 9 18 16 25 36 30 47 31 第二趟希爾排序,設增量 d = 39 18 12 11 23 16 25 31 30 47 36第三趟希爾排序,設增量 d = 1 9 11 12 16 18 23 25 30 31 36 47 28v
12、oid ShellInsert ( SqList &L, int dk ) for ( i=dk+1; i=n; +i ) if ( L.ri.key0&(L.r0.keyL.rj.key); j-=dk) L.rj+dk = L.rj; / 記錄后移,查找插入位置 L.rj+dk = L.r0; / 插入 / if / ShellInsert29void ShellSort (SqList &L, int dlta, int t) / 增量為dlta的希爾排序 for (k=0; k1) / while / BubbleSorti = n;i = lastExchan
13、geIndex; / 本趟進行過交換的 / 最后一個記錄的位置 if (Rj+1.key Rj.key) Swap(Rj, Rj+1); /iffor (j = 1; j i; j+)lastExchangeIndex = 1;lastExchangeIndex = j; /記下進行交換的記錄位置33注意注意: :2. 一般情況下,每經(jīng)過一趟“起泡”,“i 減一”,但并不是每趟都如此。例如例如:523197825531579 89i=7i=6for (j = 1; j i; j+) if (Rj+1.key Rj.key) 131. 起泡排序的結束條件為, 最后一趟沒有進行最后一趟沒有進行“交
14、換記錄交換記錄”。jjjjjji=2jj34時間分析時間分析: :最好的情況(關鍵字在記錄序列中順序有序):最好的情況(關鍵字在記錄序列中順序有序): 只需進行一趟起泡只需進行一趟起泡“比較比較”的次數(shù):的次數(shù):最壞的情況(關鍵字在記錄序列中逆序有序):最壞的情況(關鍵字在記錄序列中逆序有序): 需進行需進行n-1趟起泡趟起泡“比較比較”的次數(shù):的次數(shù):0“移動移動”的次數(shù):的次數(shù):“移動移動”的次數(shù):的次數(shù):n-12) 1() 1(2nnini2) 1(3) 1(32nnini35二、一趟快速排序(一次劃分)二、一趟快速排序(一次劃分)目標:目標:找一個記錄,以它的關鍵字作為“樞軸樞軸”,凡
15、其關鍵字小于樞軸關鍵字小于樞軸的記錄均移動至該記錄之前移動至該記錄之前,反之,凡關鍵字大于關鍵字大于樞軸樞軸的記錄均移動至該記錄之后移動至該記錄之后。致使一趟排序一趟排序之后,記錄的無序序列Rs.t將分割成兩部分分割成兩部分:Rs.i-1和Ri+1.t, 且 Rj.key Ri.key Rj.key (sji-1) 樞軸樞軸 (i+1jt)3652 49 80 36 14 58 61 97 23 75stlowhigh設設 Rs=52 為樞軸暫存在為樞軸暫存在R0的位置上的位置上 將 Rhigh.key 和 樞軸的關鍵字進行比較,要求Rhigh.key 樞軸的關鍵字 將 Rlow.key 和
16、樞軸的關鍵字進行比較,要求Rlow.key 樞軸的關鍵字high23low80high14low52例如例如R052lowhighhighhighlow37 可見,經(jīng)過“一次劃分一次劃分” ,將關鍵字序列 52, 49, 80, 36, 14, 58, 61, 97, 23, 75 調整為: 23, 49, 14, 36, (52) 58, 61, 97, 80, 75 在調整過程中,設立了兩個指針: low 和high 之后逐漸減小 high,增加 low,并保證 Rhigh.key52,和 Rlow.key52,否則進行記錄的“交換”。38int Partition (Elem R, in
17、t low, int high) pivotkey = Rlow.key; while (lowhigh) while (low=pivotkey) -high; RlowRhigh; while (lowhigh & Rlow.key=pivotkey) +low; RlowRhigh; return low; / 返回樞軸所在位置 / Partition39int Partition (Elem R ,int low, int high) / Partition R0 = Rlow; pivotkey = Rlow.key; / 樞軸 while (lowhigh) while(l
18、ow=pivotkey) - high; / 從右向左搜索Rlow = Rhigh;while (lowhigh & Rlow.key=pivotkey) + low; / 從左向右搜索Rhigh = Rlow;Rlow = R0; return low;40三、快速排序三、快速排序 首先對無序的記錄序列進行“一次劃分一次劃分”,之后分別分別對分割所得兩個子序列“遞歸遞歸”進行快速排序進行快速排序。無 序 的 記 錄 序 列無序記錄子序列(1)無序子序列(2)樞軸樞軸一次劃分分別進行快速排序41void QSort (SqList &L, int low, int high )
19、 / 對記錄序列L.rlow.high進行快速排序 if (low high-1) / 長度大于1 / QSortpivotloc = Partition(L, low, high); / 對 L.rlow.high 進行一次劃分一次劃分QSort(L, low, pivotloc-1); / 對低子序列遞歸排序,pivotloc是樞軸位置是樞軸位置QSort(L, pivotloc+1, high); / 對高子序列遞歸排序42void QuickSort( SqList & L) / 對順序表進行快速排序 QSort(L, 1, L.length); / QuickSort 第一次
20、調用函數(shù) Qsort 時,待排序記錄序列的上、下界分別為 1 和 L.length。43四、快速排序的時間分析四、快速排序的時間分析假設一次劃分所得樞軸位置 i=k,則對n 個記錄進行快排所需時間其中 Tpass(n)為對 n 個記錄進行一次劃分所需時間, 若待排序列中記錄的關鍵字是隨機分布的,則 k 取 1 至 n 中任意一值的可能性相同。T(n) = Tpass(n) + T(k-1) + T(n-k)44nkavgavgavgknTkTnCnnT1)() 1(1)(設 Tavg(1)b則可得結果:) 1ln() 1)(22()(nncbnTavg結論結論: 快速排序的時間復雜度為快速排序
21、的時間復雜度為O(nlogn)由此可得快速排序所需時間的平均值為:45 若待排記錄的初始狀態(tài)為按關鍵字有序若待排記錄的初始狀態(tài)為按關鍵字有序時,快速排序將蛻化為起泡排序時,快速排序將蛻化為起泡排序,其時間復雜度為O(n2)。 為避免出現(xiàn)這種情況,需在進行一次劃分之前,進行“予處理予處理”,即: 先對 R(s).key, R(t).key 和 R(s+t)/2.key,進行相互比較,然后取取關鍵字為 “三者之三者之中中”的記錄為樞軸為樞軸記錄。4610.4 堆堆 排排 序序簡簡 單單 選選 擇擇 排排 序序堆堆 排排 序序47一、簡單選擇排序一、簡單選擇排序假設排序過程中,待排記錄序列的狀態(tài)為:
22、有序序列R1.i-1無序序列 Ri.n 第 i 趟簡單選擇排序從中選出關鍵字最小的記錄有序序列R1.i無序序列 Ri+1.n48簡單選擇排序的算法描述如下:void SelectSort (Elem R, int n ) / 對記錄序列R1.n作簡單選擇排序。 for (i=1; i0; -i ) HeapAdjust ( R, i, n ); / 建大頂堆for ( i=n; i1; -i ) R1Ri; / 將堆頂記錄和當前未經(jīng)排序子序列 / R1.i中最后一個記錄相互交換 HeapAdjust(R, 1, i-1); / 對 R1 進行篩選54如何如何“建堆建堆”?兩個問題兩個問題:如何
23、如何“篩選篩選”?定義堆類型為定義堆類型為:typedef SqList HeapType; / 堆采用順序表表示之55所謂“篩選篩選”指的是,對一棵左/右子樹均為堆的完全二叉樹,“調整調整”根結根結點點使整個二叉樹也成為一個堆。堆堆篩選篩選5698814973556412362740例如例如:是大頂堆是大頂堆12但在 98 和 12 進行互換之后,它就不不是堆了因此,需要對它進行“篩選”98128173641298比較比較比較57void HeapAdjust (Elem &R, int s, int m) / 已知 Rs.m中記錄的關鍵字除 Rs 之外均 / 滿足堆的特征,本函數(shù)自
24、上而下調整 Rs 的 / 關鍵字,使 Rs.m 也成為一個大頂堆。 / HeapAdjustrc = Rs; / 暫存 Rs for ( j=2*s; j= Rj.key ) break; / 再作“根”和“子樹根”之間的比較, / 若“=”成立,則說明已找到 rc 的插 / 入位置 s ,不需要繼續(xù)往下調整Rs = Rj; s = j; / 否則記錄上移,尚需繼續(xù)往下調整if ( jm & Rj.keyRj+1.key ) +j; / 左/右“子樹根”之間先進行相互比較 / 令 j 指示關鍵字較大記錄的位置59建堆是一個從下往上進行建堆是一個從下往上進行“篩選篩選”的過程。的過程。4
25、0554973816436122798例如例如: 排序之前的關鍵字序列為123681734998817355 現(xiàn)在,左/右子樹都已經(jīng)調整為堆,最后只要調整根結點,使整個二叉樹是個“堆”即可。9849406436122760堆排序的時間復雜度分析:堆排序的時間復雜度分析:1. 對深度為 k 的堆,“篩選”所需進行的關鍵字比較的次數(shù)至多為2(k-1);2. 對 n 個關鍵字,建成深度為 h (=log2n+1) 的堆,所需進行的關鍵字比較的次數(shù)至多 4n;3. 調整“堆頂” n-1 次,總共進行的關鍵 字比較的次數(shù)不超過 2 ( log2(n-1) + log2(n-2) + +log22) 2n
26、( log2n ) 因此,堆排序的時間復雜度為O(nlogn)6110.5 歸歸 并并 排排 序序歸并排序的過程基于下列基本思想基本思想進行: 將兩個或兩個以上的有序子序列 “歸并” 為一個有序序列。62在內部排序中,通常采用的是2-路歸并排序。即:將兩個位置相鄰位置相鄰的記錄有序子序列歸并為一個一個記錄的有序序列。有有 序序 序序 列列 Rl.n有序子序列有序子序列 Rl.m有序子序列有序子序列 Rm+1.n這個操作對順序表而言,是輕而易舉的。63void Merge (Elem SR, Elem TR, int i, int m, int n) / 將有序的記錄序列 SRi.m 和 SRm
27、+1.n / 歸并為有序的記錄序列 TRi.n / Mergefor (j=m+1, k=i; i=m & j=n; +k) / 將SR中記錄由小到大地并入TR if (SRi.key=SRj.key) TRk = SRi+; else TRk = SRj+; 64if (i=m) TRk.n = SRi.m; / 將剩余的 SRi.m 復制到 TRif (j=n) TRk.n = SRj.n; / 將剩余的 SRj.n 復制到 TR65歸并排序的算法歸并排序的算法如果記錄無序序列 Rs.t 的兩部分 Rs. (s+t)/2 和 R (s+t)/2 +1.t分別按關鍵字有序,則利用上述
28、歸并算法很容易將它們歸并成整個記錄序列是一個有序序列。 由此,應該先分別對這兩部分進行 2-路歸并排序。66例如:例如:52, 23, 80, 36, 68, 14 (s=1, t=6) 52, 23, 80 36, 68, 14 52, 23 80 52 23, 52 23, 52, 8036, 68 143636, 6814, 36, 68 14, 23, 36, 52, 68, 80 23 52 23 36 68 80146867void Msort ( Elem SR, Elem &TR1, int s, int t ) / 將SRs.t 歸并排序為 TR1s.t if (s= =t) TR1s=SRs; else / Msort 68m = (s+t)/2; / 將SRs.t平分為SRs.m和SRm+1.tMsort (SR, TR2, s, m); / 遞歸地將SRs.m歸并為有序的TR2s.mMsort (SR, TR2, m+1, t); /遞歸地SRm+1.t歸并為有序的TR2m+1.tMerge (TR2, TR1, s, m, t); / 將TR2s.m和TR2m+1.t歸并到TR1s.t69void MergeSort (SqList &L) / 對順序表 L 作2-路歸并排序。 MSort(R, R, 1, n); / Merge
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年幼兒園小班上學期班務總結模版
- 主播簡約合同范例
- 創(chuàng)新型醫(yī)療器械的臨床試驗設計
- 供貨安裝安全合同樣本
- 醫(yī)療保健領域中區(qū)塊鏈UI的改進方案
- 供貨擔保合同范例
- 公司委托經(jīng)營代理合同范例
- 醫(yī)療倫理醫(yī)護人員在緊急情況下的責任與擔當
- 醫(yī)療物聯(lián)網(wǎng)IoT中區(qū)塊鏈技術的隱私保護探討
- 公共廁所看管合同范例
- 2024年廣東省茂名市小升初數(shù)學試卷
- 農(nóng)藝工教學計劃及大綱
- 施工焊接與質量控制
- 二年級下冊口算題1000題大全-
- 汽車前圍板拉延成形模面及工藝優(yōu)化
- 聯(lián)邦學習的隱私保護機制分析
- 2024房產(chǎn)抵賬協(xié)議書范本
- 初中英語比較級和最高級專項練習題含答案
- MOOC 英語口語進階-南京大學 中國大學慕課答案
- 熱輻射的一般知識
- 科普活動創(chuàng)新項目申報計劃書
評論
0/150
提交評論