內(nèi)部排序和外部排序_第1頁
內(nèi)部排序和外部排序_第2頁
內(nèi)部排序和外部排序_第3頁
內(nèi)部排序和外部排序_第4頁
內(nèi)部排序和外部排序_第5頁
已閱讀5頁,還剩39頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、的數(shù)據(jù)很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。我們這里說說八大排序就是內(nèi)部排序。直接插入排序插入排序壽爾排序使用內(nèi)存內(nèi)部排序廿簡單選擇排序選擇排序帆堆排序冒泡排序快速排序交換排序排序歸并排序基數(shù)排序內(nèi)存和外村結(jié)合使用外部排序當n較大,則應(yīng)采用時間復(fù)雜度為 O(nlog2n)的排序方法:快速排序、堆排序或歸并排序序??焖倥判颍菏悄壳盎诒容^的內(nèi)部排序中被認為是最好的方法,當待排序的關(guān)鍵字是隨機分布時,快速排序的平均時間最短;1.插入排序一直接插入排序(Straight Insertion Sort)基本思想:將一個記錄插入到已排序好的有序表中,從而得到一個新,記錄數(shù)增1的有序

2、表。即:先將序列的第1個記錄看成是一個有序的子序列,然后從第2個記錄逐個進行插入,直至整個序列有序為止。要點:設(shè)立哨兵,作為臨時存儲和判斷數(shù)組邊界之用。直接插入排序示例:初始關(guān)整字:h(49)3&659776132749(38)49>659776132749(65)(3849+65)97J132749<97)(384965i97)132775(76)(384965廠7697132749i=6f(13J<13384965769727祐(27)(133649唱5 *769?)49(49><13273849657697)t監(jiān)視響如果碰見一個和插入元素相等的,那么

3、插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后順序沒有改變,從原無序序列出去的順序就是排好序后的順序,所以插入排序是穩(wěn)定的。算法的實現(xiàn):void print( int a, int n , int i)coutvvi <<":"for ( int j= 0; j<8; j+)cout<<aj <<""coutvvendl;void InsertSort( int a, int n)..2.for ( int i= 1; i<n; i+)13.if

4、 (a【i < a【i-1)入。小于的話,移動有序表后插入/若第i個元素大于14.int j= i-1;15.int x = ai;/復(fù)制為哨兵,即存儲待排序元素16.ai = ai-1;/先后移一個元素17.while (x < aj)/查找在有序表的插入位置18.aj+1 = aj;19.j-;/元素后移20.21.aj+1 = x;/插入到正確位置22.23.print(a,n,i);/打印每趟排序的結(jié)果7.28.int main()29.int a8 = 3,1,5,7,2,4,9,6;30.InsertSort(a,8);31.print(a,8,8)

5、;32.i-1 元素,直接插效率:時間復(fù)雜度:0 ( nA2 ).其他的插入排序有二分插入排序,2-路插入排序。2.插入排序一希爾排序(Shell's Sort )希爾排序是1959年由D.L.Shell提出來的,相對直接排序有較大的改進。小增量排序基本思想:希爾排序又叫縮先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,待整個序列中的記錄 時,再對全體記錄進行依次直接插入排序?;居行虿僮鞣椒?1. 選擇一個增量序列 t1 , t2,,tk,其中ti>tj , tk=1 ;2. 按增量序列個數(shù)k,對序列進行k趟排序;3. 每趟排序,根據(jù)對應(yīng)的 增量ti,將待排序列

6、分割成若干長度為m的子序列,分別對各子表進行直接插入排序。僅增量因子為1時,整個序列作為一個表來處理,表長度即為整個序列的長度。希爾排序的示例:初始關(guān)躍字n4938659776132749550449|13t-38L2765L499755 76 u04 j一趟排序結(jié)果:i13274?55044938659776r13r?762? |0465|4?9,7 |二趙排序結(jié)果;13044938274955059776三趙排序結(jié)果:04132738 -J4$4955657697算法實現(xiàn):我們簡單處理增量序列:增量序列d = n/2 ,n/4, n/8 1n為要排序數(shù)的個數(shù)..

7、6.37.38.即:先將要排序的一組記錄按某個增量 d(n/2,n為要排序數(shù)的個數(shù))分成若干組子序列, 每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然后再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。繼續(xù)不斷縮小增量直至為1,最后使用直接插入排序完成排序。void print( int a, int n , int i)coutvvi <<":"for ( int j

8、= 0; j<8; j+)cout<<aj <<""coutvvendl;/*直接插入排序的一般形式* param int dk縮小增量,如果是直接插入排序,dk=1*/void ShelllnsertSort(int a,for ( int i= dk; i<n; +i)if (ai < ai-dk)小于的話,移動有序表后插入int j = i-dk;int x = ai;ai = ai-dk;while (x < aj)aj+dk = aj;j -= dk;aj+dk = x;print (a, n,i );int n,

9、int dk)/若第i個元素大于i-1元素,直接插入。/復(fù)制為哨兵,即存儲待排序元素/首先后移一個元素/查找在有序表的插入位置/元素后移/插入到正確位置/*先按增量d (n/2,n為要排序數(shù)的個數(shù)進行希爾排序*/39.int dk = n/2;40.while ( dk >= 1 )41.ShelllnsertSort(a, n, dk);42.dk = dk/2;43.44.45.int main()46.int a8 = 3,1,5,7,2,4,9,6;47./ShellInsertSort(a,8,1); /直接插入排序48.shellSort(a,8);/希爾插入排序49.pri

10、nt(a,8,8);50.希爾排序時效分析很難,關(guān)鍵碼的比較次數(shù)與記錄移動次數(shù)依賴于增量因子序列d的選取,特定情況下可以準確估算出關(guān)鍵碼的比較次數(shù)和記錄的移動次數(shù)。目前還沒有人給出選取最好的增量因子序列的方法。增量因子序列可以有各種取法,有取奇數(shù)的,也有取質(zhì)數(shù)的,但需要注意:增量因子中除 1外沒有公因子,且最后一個增量因子必須為1。希爾排序方法是一個不穩(wěn)定的排序方法。3.選擇排序一簡單選擇排序(Simple Selection Sort )基本思想:在要排序的一組數(shù)中,選出最?。ɑ蛘咦畲螅┑囊粋€數(shù)與第i個位置的數(shù)交換;然后在剩下的數(shù)當中再找最小 (或者最大)的與第2個位置的數(shù)交換,依次類推,直

11、到第n-1個元素(倒數(shù)第二個數(shù))和第 n個元素(最后一個數(shù))比較為止。簡單選擇排序的示例:void shellSort(int a, int n)return k;..8.值&口i.初尚_尚一肖-尚一肖-S-尚一肖- - ILL _Ffull d I -_ L-fa fa » .LB- e - LJ - - LI. - LI. - - - k- 12345678 g.rg.rj學(xué)r扌H'glh-lnn 旨一B'3157249613S7249612E?34?6123?5496123

12、45796123457961234569?123456?9123456?9操作萬法:第一趟,從n個記錄中找出關(guān)鍵碼最小的記錄與第一個記錄交換;第二趟,從第二個記錄開始的n-1個記錄中再選出關(guān)鍵碼最小的記錄與第二個記錄交換;以此類推.第i趟,則從第i個記錄開始的n-i+1個記錄中選出關(guān)鍵碼最小的記錄與第i個記錄交換,直到整個序列按關(guān)鍵碼有序。算法實現(xiàn):void print( int a, int n , int i)cout«"第"i+1 <<"趟:";for ( int j= 0; j<8; j+)cout<<aj

13、 <<""coutvvendl;/*數(shù)組的最小值* return int數(shù)組的鍵值*/int SelectMinKey(int a,int n, int i)intk = i;for(int j=i+1 ;j< n; +j) if (ak > aj) k = j;..6./* *選擇排序*/void selectSort( int a, int n) int key, tmp

14、;for ( int i = 0; i< n; +i) /選擇最小的元素/最小元素與第i位key = SelectMinKey(a, n,i);if (key != i)tmp = ai; ai = akey; akey = tmp;置元素互換print (a, n , i);int main()int a8 = 3,1,5,7,2,4,9,6;coutvv "初始值:”;for ( int j= 0; j<8; j+) cout<<aj <<""coutvvendlvvendl;selectSort(a, 8);print(a

15、,8,8);簡單選擇排序的改進二元選擇排序簡單選擇排序,每趟循環(huán)只能確定一個元素排序后的定位。我們可以考慮改進為每趟循環(huán)確定兩個元素(當前趟最大和最小記錄)的位置,從而減少排序所需的循環(huán)次數(shù)。改進后對n個數(shù)據(jù)進行排序,最多只需進行 n/2趟循環(huán)即可。具體實現(xiàn)如下:void SelectSort( int r, int n) int i ,j , min ,max, tmp;for (i=1 ;i <= n/2;i+) / 做不超過n/2趟選擇排序min = i; max = i ;/ 分別記錄最大和最小關(guān)鍵字記錄位置for (j= i+1; j<= n-i; j+) 7.if (r

16、j > rmax) 7.18.19.max = j ;continueif (rj< rmin) min = j ;/該交換操作還可分情況討論以提高效率tmp = ri-1; ri-1 = rmin; rmin = tmp;tmp = rn-i; rn-i = rmax; rmax = tmp;4.選擇排序一堆排序(Heap Sort )堆排序是一種 樹形選擇排序,是對直接選擇排序的有效改進?;舅枷耄憾训亩x如下:具有 n個元素的序列(k1,k2,.,kn),當且僅當滿足時稱之為堆。由堆的定義可以看出,堆頂元素(即第一個元素)必

17、為最小項(小頂堆)(或不若以一維數(shù)組存儲一個堆,則堆對應(yīng)一棵完全二叉樹,且所有非葉結(jié)點的值均不大于 小于)其子女的值,根結(jié)點(堆頂元素)的值是最小(或最大)的。如:(a)大頂堆序列:(96, 83,27,38,11,09)(b)小頂堆序列:(12,36,24,85,47, 30,53,91)初始時把要排序的n個數(shù)的序列看作是一棵順序存儲的二叉樹(一維數(shù)組存儲二叉樹),調(diào)整它們的存儲序, 使之成為一個堆,將堆頂元素輸出, 得到n個元素中最小(或最大)的元 素,這時堆的根節(jié)點的數(shù)最小(或者最大)。然后對前面(n-1)個元素重新調(diào)整使之成為堆,輸出堆頂元素,得到 n個元素中次?。ɑ虼未螅┑脑?。依此

18、類推,直到只有兩個節(jié)點的堆, 并對它們作交換,最后得到有 n個節(jié)點的有序序列。稱這個過程為 堆排序。因此,實現(xiàn)堆排序需解決兩個問題:1. 如何將n個待排序的數(shù)建成堆;2. 輸出堆頂元素后,怎樣調(diào)整剩余n-1個元素,使其成為一個新堆。首先討論第二個問題:輸出堆頂元素后,對剩余n-1元素重新建成堆的調(diào)整過程。調(diào)整小頂堆的方法:1) 設(shè)有m個元素的堆,輸出堆頂元素后,剩下m-1個元素。將堆底元素送入堆頂(最 后一個元素與堆頂進行交換),堆被破壞,其原因僅是根結(jié)點不滿足堆的性質(zhì)。2)將根結(jié)點與左、右子樹中較小元素的進行交換。3)若與左子樹交換:如果左子樹堆被破壞,即左子樹的根結(jié)點不滿足堆的性質(zhì),則重復(fù)

19、方 法(2).4 )若與右子樹交換,如果右子樹堆被破壞,即右子樹的根結(jié)點不滿足堆的性質(zhì)。則重復(fù)方 法(2).5)繼續(xù)對不滿足堆性質(zhì)的子樹進行上述交換操作,直到葉子結(jié)點,堆被建成。稱這個自根結(jié)點到葉子結(jié)點的調(diào)整過程為篩選。如圖:91J304799?7n«s1) n個結(jié)點的完全二叉樹,則最后一個結(jié)點是第仝上個結(jié)點的子樹。2)篩選從第皿»個結(jié)點為根的子樹開始,該子樹成為堆。<a>無呼序列* Cb) 97被篇選之后的我務(wù)* (c) 6S醸篩選之后的狀態(tài)t(d) 38威揣送之疳的狀態(tài)'(e) 49聯(lián)龍選之后世成的堆再討論對n個元素初始建堆的過程。建堆方法:對初始序

20、列建堆的過程,就是一個反復(fù)進行篩選的過程。3 )之后向前依次對各結(jié)點為根的子樹進行篩選,使之成為堆,直到根結(jié)點。如圖建堆初始過程:無序序列:(49,38,65,97, 76,13,27, 49)b,堆被皓壞"眼V 點子女交檢3錯出車嗎C.仃子押不淌足堆. 其鶴與蠱子女左橫d.爼 r;£ 'iprint(H,length);..3.34.35.算法的實現(xiàn):從算法描述來看,堆排序需要兩個過程, 一是建

21、立堆,二是堆頂與堆的最后一個元素交換位 置。所以堆排序有兩個函數(shù)組成。一是建堆的滲透函數(shù),二是反復(fù)調(diào)用滲透函數(shù)實現(xiàn)排序的 函數(shù)。void print( int a, int n)for ( int j= 0; j<n; j+)cout<<aj <<""coutvvendl;/*已知Hsm除了 Hs外均滿足堆的定義*調(diào)整Hs,使其成為大頂堆.即將對第s個結(jié)點為根的子樹篩選* param H是待調(diào)整的堆數(shù)組* param s是待調(diào)整的數(shù)組元素的位置* param length 是數(shù)組的長度*/void HeapAdjust( int H, int

22、s, int length)int tmp = Hs;int child = 2*s+1;/左孩子結(jié)點的位置。(i+1為當前調(diào)整結(jié)點的右孩子結(jié)點的位置)while (child < length) if (child+1 vlength && Hchild<Hchild+1) /如果右孩子大于左孩子(找到比當前待調(diào)整結(jié)點大的孩子結(jié)點)+child ;if (Hs<Hchild) /Hs = Hchild;/s = child;/child = 2*s+1;else /整,直接退岀breakHs = tmp;如果較大的子結(jié)點大于父結(jié)點那么把較大的子結(jié)點往上移動,

23、替換它的父結(jié)點重新設(shè)置s ,即待調(diào)整的下一個結(jié)點的位置如果當前待調(diào)整結(jié)點大于它的左右孩子,則不需要調(diào)/當前待調(diào)整的結(jié)點放到比其大的孩子結(jié)點位置上5.76.77.*初始堆進行調(diào)整* 將 H0.length-1 建成堆*調(diào)整完之后第一個元素是序列的最小的元素*/ void BuildingHeap( int H, int length)/最后一個有孩子的節(jié)點的位置i

24、= (length -1) / 2for ( int i = (length -1) / 2 ; i >= 0; -i)HeapAdjust(H,i,length);/*堆排序算法*/void HeapSort( int H, int length)/初始堆BuildingHeap(H, length);/從最后一個元素開始對序列進行調(diào)整for ( int i = length - 1; i > 0; -i)/交換堆頂元素H0和堆中最后一個元素int temp = Hi; Hi = H0; H0 = temp;/每次交換堆頂元素和堆中最后一個元素之后,都要對堆進行調(diào)整HeapAdj

25、ust(H,0,i); int main()int H10 = 3,1,5,7,2,4,9,6,10,8; coutvv "初始值:”; print(H,10);HeapSort(H,10);selectSort(a, 8);cout«"結(jié)果:"print(H,10);分析:設(shè)樹深度為k, |才=】。鬥丹+1。從根到葉的篩選,元素比較次數(shù)至多2(k-1)次,交換記錄至多k次。所以,在建好堆后,排序過程中的篩選次數(shù)不超過下式:2(LlogllJ+llogi <«2j+* + logi 2X2n(Llog2 «J)而建堆時的比較次數(shù)

26、不超過4n次,因此堆排序最壞情況下,時間復(fù)雜度也為:0(nlogn )。5.交換排序一冒泡排序(Bubble Sort )基本思想:在要排序的一組數(shù)中, 對當前還未排好序的范圍內(nèi)的全部數(shù),自上而下對相鄰的兩個數(shù)依次進行比較和調(diào)整,讓較大的數(shù)往下沉,較小的往上冒。即:每當兩相鄰的數(shù)比較后發(fā)現(xiàn)它們的排序與排序要求相反時,就將它們互換。冒泡排序的示例:3838659497761327一49初她關(guān)蜜字76B274997第一趙排序后第二趟排序后第三葩排序后3 7 9 ¥12 4-47 18 92 3 4第五趨排序S排序后算法的實現(xiàn):1.void bubbleSort( int a, int n

27、)2.for ( inti =0 ; i< n-1; +i) 3.for(int j = 0; j < n-i-1; +j) 4.if (aj > aj+1)5.6.int tmp = aj ; aj = aj+1 ; aj+1 = tmp;0.冒泡排序算法的改進對冒泡排序常見的改進方法是加入一標志性變量excha nge,用于標志某一趟排序過程中是否有數(shù)據(jù)交換,如果進行某一趟排序時并沒有進行數(shù)據(jù)交換,則說明數(shù)據(jù)已經(jīng)按要求排列好, 可立即結(jié)束排序,避免不必要的比較過程。本文再提供以下兩種改進算法:1 設(shè)置一標志性變量 pos,用于記錄每趟排序中最后一次進行交換的

28、位置。由于pos位置之后的記錄均已交換到位,故在進行下一趟排序時只要掃描到pos位置即可。改進后算法如下:1.void Bubble_1 (int r,int n) 2.int i= n1;/初始時,最后位置保持不變3.while ( i> 0) 4.intpos= 0;/每趟開始時,無記錄交換5.for(int j= 0; j< i; j+)6.if (rj> rj+1) 7.pos= j;/記錄交換的位置8.inttmp = rj; rj=rj+1;rj+1=tmp;9.10.i= pos;/為下一趟排序作準備11.12.2傳統(tǒng)冒泡排序中每一趟排序操作只能找到一個最大值或

29、最小值,我們考慮利用在每趟排序中進行正向和反向兩遍冒泡的方法一次可以得到兩個最終值(最大者和最小者),從而使排序趟數(shù)幾乎減少了一半。改進后的算法實現(xiàn)為:1. void Bubble_2 ( int r, int n)2. intlow = 0;3. inthigh=n-1;/設(shè)置變量的初始值4. inttmp,j;5. while (low < high) .3.14.for (j= low; j< high; +j)if (rj> rj+1) tmp = rj; rj=rj+1;rj+1=tmp;-high;for ( j=high; j&

30、gt;low; -j)if (rj<rj-1) tmp = rj; rj=rj-1;rj-1=tmp;/正向冒泡,找到最大者/修改high值,前移一位/反向冒泡,找到最小者15. +low;16. 17. /修改low值,后移一位6.交換排序快速排序(Quick Sort )基本思想:1)選擇一個基準元素,通常選擇第一個元素或者最后一個元素,2 )通過一趟排序講待排序的記錄分割成獨立的兩部分,其中一部分記錄的元素值均比基準 元素值小。另一部分記錄的 元素值比基準值大。3)此時基準元素在其排好序后的正確位置4)然后分別對這兩部分記錄用同樣的方法繼續(xù)進行排序,直到整個序列有序。快速排序的示例

31、:(a) 趟排序的過程:初始戔犍字pivot key491IISB659?761327J,1 j進行1次交換之后27386S4977613Jf.I J49進行2擾交換之后27385776)34165A+5進行3次交換之后2738u97766549.f4斗i1 i1| j逬行4次交換之后273837697t6549j*J完成一超排序2738134976976549(a)(b)排序的全過程初蠟狀蠱4938659776132749一次劃分之后(27384976976549分別進行快速排序132738結(jié)康結(jié)東4965769749(65)赭東結(jié)束有洋序列1327334949657697(b)算法的實現(xiàn):

32、遞歸實現(xiàn):1. void print( int a, int n)2. for ( int j= 0; j<n; j+)3. cout<<aj <<""4.5.coutvvendl;6.7.8.void swap( int *a, int *b)9.10.int tmp = *a;11.*a = *b;12.*b = tmp;13.14.15.int partition(int a,int low,int high)16.17.int privotKey = alow;18.while (low < high)替地向中間掃描19.whil

33、e (low < high && ahigh >= privotKey) -high;high所指位置向前搜索,至多到 low+1 位置。將比基準元素小的交換到低端20.swap(&alow, & ahigh);21.while (low < high && alow <= privotKey ) +low;22.swap(&alow, & ahigh);23.24.print(a,10);25.return low;9.void quickSort(int a,int low,int

34、high)30.if (low < high)31.int privotLoc = partition(a, low, high);32.quickSort(a, low, privotLoc -1);序33.quickSort(a, privotLoc + 1, high);序7.int main()38.int a10 = 3,1,5,7,2,4,9,6,10,8;39.cout<<"初始值:”;40.print(a,10);41.quickSort(a,0,9);42.cout<<"結(jié)果:"43.print(

35、a,10);II基準元素/從表的兩端交II從II將表一分為二II遞歸對低子表遞歸排II遞歸對高子表遞歸排..2.分析:快速排序是通常被認為在同數(shù)量級(0(nIog2n)的排序方法中平均性能最好的。但若初始序列按關(guān)鍵碼有序或基本有序時,快排序反而蛻化為冒泡排序。為改進之,通常以三者取中法”來選取基準記錄,即將排序區(qū)間的兩個端點與中點三個記錄關(guān)鍵碼居中的調(diào)整為支點 記錄??焖倥判蚴且粋€不穩(wěn)定的排序方法。快速排序的改進在本改進算法中,只對長度大于k的子序列遞歸調(diào)用快速排序,讓原序列基

36、本有序,然后再對 整個基本有序序列用插入排序算法排序。實踐證明,改進后的算法時間復(fù)雜度有所降低,且當k取值為8左右時,改進算法的性能最佳。算法思想如下:void print( int a, int n)for ( int j= 0; j<n; j+)cout<<aj <<""coutvvendl; void swap( int *a, int *b) int tmp = *a;*a = *b;*b = tmp;int partition(int a,int privotKey = alow;int low,int high)/基準元素while

37、 (low < high)/從表的兩端交替地向中間掃描while (low < high&& ahigh >=privotKey) -high;/從high 所指位置向前搜索,至多到Iow+1位置。將比基準元素小的交換到低端swap(&alow, & ahigh);while (low < high && alow <= privotKey ) +low;swap(&alow, & ahigh);print(a,10);return low; void qsort_improve( int r , i

38、nt low, int high, int k)if ( high -low > k ) /長度大于k時遞歸,k為指定的數(shù)算法保持int pivot = partition(r, low, high);/ 調(diào)用的 Partition不變qsort_improve(r, low, pivot - 1,k);qsort_improve(r, pivot + 1, high,k);void quickSort( int r, int n, int k)qsort_improve(r,0,n,k);/先調(diào)用改進算法Qsort 使之基本有序/再用插入排序?qū)居行蛐蛄信判騠or ( int i=1

39、; i<=n;i +)int tmp = ri;int j=i-1;while (tmp < rj)rj+1=rj; j=j-1;rj+1 = tmp; int main()int a10 = 3,1,5,7,2,4,9,6,10,8; cout<< "初始值:”; print(a,10);quickSort(a,9,4);cout<< "結(jié)果:"3

40、.0.61.print(a,10);7.歸并排序(Merge Sort )基本思想:歸并(Merge)排序法是將兩個(或兩個以上)有序表合并成一個新的有序表,即把待排序序列分為若干個 子序列,每個子序列是有序的。然后再把有序子序列合并為整體有序序列。歸并排序示例:字11(76J (13J t|(2?) ti歸并NJB【算嚴US嚴n 嚴】149L1327科】C1327J酣76»7合并方法:設(shè)rin由兩個有序子表rim和rm+1n組成,兩個子表長度分別為n-i +1、n-m <1. j=m+1 ; k=i ; i=i; /置兩個子表的起始下標及

41、輔助數(shù)組的起始下標2. 若i>m或j>n,轉(zhuǎn)其中一個子表已合并完,比較選取結(jié)束3. 選取ri和rj較小的存入輔助數(shù)組rf如果 ri<rj,rfk=ri ; i+ ;k+ ;轉(zhuǎn)否則,rfk=rj ; j+ ;k+ ;轉(zhuǎn)4. /將尚未處理完的子表中元素存入rf如果i<=m,將rim存入rfkn /前一子表非空如果jv=n ,將rjn存入rfkn/后一子表非空5. 合并結(jié)束。1. /將rim和rm +1n歸并到輔助數(shù)組 rfin2. void Merge(ElemType *r,ElemType *rf,int i, int m, int n)3. 4. int j,k;5.

42、for (j=m+1,k=i; i<=m && j <=n ; +k)...5.if (rj < ri) rfk = rj+; else rfk = ri+;while (i <= m) rfk+ = ri+; while (j <= n) rfk+ = rj+;歸并的迭代算法1個元素的表總是有序的。所以對 n個元素的待排序列,每個元素可看成1個有序子表。對子表兩兩合并生成 n/2個子表,所得子表除最

43、后一個子表長度可能為1夕卜,其余子表長度均為2。再進行兩兩合并,直到生成n個元素按關(guān)鍵碼有序的表。void print( int a, int n)for ( int j= 0; j<n; j+)cout<<aj <<""coutvvendl;/將rim和rm +1n歸并到輔助數(shù)組 rfinvoidMerge(ElemType *r,ElemType *rf,int i,int m, int n)intj,k;for(j=m+1,k=i; i<=m && j <=n ; +k)if (rj < ri) rfk

44、= rj+;else rfk = ri+;while (i <= m) rfk+ = ri+;while (j <= n) rfk+ = rj+;print(rf,n+1);void MergeSort(ElemType *r, ElemType *rf,int lenght)int len = 1;ElemType *q = r ;ElemType *tmp ;26.while (len < lenght) 27.int s = len;28.len = 2 * s ;29.int i = 0;30.while (i+ len <lenght)31.Merge(q,

45、rf, i, i+ s-1, i+ len-1 );/對等長的兩個子表合并32.i = i+ len;33.34.if (i + s < lenght)35.Merge(q, rf, i, i+ s -1, lenght -1);/對不等長的兩個子表合并36.37.tmp = q; q = rf; rf = tmp;/交換q,rf,以保證下一趟歸并時,仍從q歸并到 main()43.int a10 = 3,1,5,7,2,4,9,6,10,8;44.int b10;45.MergeSort(a, b, 10);46.print(b,10);47.c

46、out«"結(jié)果:"48.print(a,10);49.50.兩路歸并的遞歸算法1.void MSort(ElemType *r, ElemType *rf,int s, int t)2.3.ElemType *rf2;4.if (s=t) rs = rfs;5. m=(s+t)/2;/*平分*p表*/8.MSort(r, rf2, s, m);/*遞歸地將psm歸并為有序的p2s m*/9.MSort(r, rf2, m+1, t);/*遞歸地將pm+1t歸并為有序的p2m+1 t*/10.Merge(rf2, rf, s, m+1,t);/*將p2sm和p2m+1t歸并到p1s t*/11. 12. int n)13. void MergeSort_recursive(ElemType *r, ElemType *rf,14. /*對順序表*p作歸并排序*/15. MSort(r, rf, 0, n-1);16. 8.桶排序/基數(shù)排序(Radix Sort)說基數(shù)排序之前,我們先說桶排序:基本思想:是將陣列分到有限數(shù)量的桶子里。每個桶子再個別排序(有可能再使用別的排序算法或是以遞回方式繼續(xù)使用桶排序進行排序)。桶排序是鴿巢排序的一種歸納結(jié)果。當要被

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論