第7章 排序
一、選擇題
1.某內排序方法的穩定性是指( D )。
A.該排序算法不允許有相同的關鍵字記錄 B.該排序算法允許有相同的關鍵字記錄
C.平均時間為0(n log n)的排序方法 D.以上都不對
2.下面給出的四種排序法中( D )排序法是不穩定性排序法。
A. 插入 B. 冒泡 C. 二路歸並 D. 堆
3.下列排序算法中,其中( D )是穩定的。
A. 堆排序,冒泡排序 B. 快速排序,堆排序
C. 直接選擇排序,歸並排序 D. 歸並排序,冒泡排序
4.穩定的排序方法是( B )
A.直接插入排序和快速排序 B.折半插入排序和起泡排序
C.簡單選擇排序和四路歸並排序 D.樹形選擇排序和shell排序
5.下列排序方法中,哪一個是穩定的排序方法?( B )
A.直接選擇排序 B.二分法插入排序 C.希爾排序 D.快速排序
6.若要求盡可能快地對序列進行穩定的排序,則應選(B)。
A.快速排序 B.歸並排序 C.冒泡排序
7.如果待排序序列中兩個數據元素具有相同的值,在排序前后它們的相互位置發生顛倒,則稱該排序算法是不穩定的。( CE )就是不穩定的排序方法。
A.起泡排序 B.歸並排序 C.Shell排序 D.直接插入排序 E.簡單選擇排序
8.若要求排序是穩定的,且關鍵字為實數,則在下列排序方法中應選(A )排序為宜。
A.直接插入 B.直接選擇 C.堆 D.快速 E.基數
9.若需在O(nlog2n)的時間內完成對數組的排序,且要求排序是穩定的,則可選擇的排序方法是( C )。
A. 快速排序 B. 堆排序 C. 歸並排序 D. 直接插入排序
10.下面的排序算法中,不穩定的是( CDF )
A.起泡排序 B.折半插入排序 C.簡單選擇排序 D.希爾排序 E.基數排序 F.堆排序。
11.下列內部排序算法中:
A.快速排序 B.直接插入排序 C. 二路歸並排序 D. 簡單選擇排序 E. 起泡排序 F. 堆排序
(1) 其比較次數與序列初態無關的算法是( DC ) (2)不穩定的排序算法是( ADF )
(3)在初始序列已基本有序(除去n個元素中的某k個元素后即呈有序,k<<n)的情況下,排序效率最高的算法是(B )
(4)排序的平均時間復雜度為O(n•logn)的算法是(ACF )為O(n•n)的算法是(BDE )
12.排序趟數與序列的原始狀態有關的排序方法是( CD )排序法。
A.插入 B. 選擇 C. 冒泡 D. 快速
13.下面給出的四種排序方法中,排序過程中的比較次數與排序方法無關的是。( A )
A.選擇排序法 B. 插入排序法 C. 快速排序法 D. 堆積排序法
14.對下列四種排序方法,在排序中關鍵字比較次數同記錄初始排列無關的是( BD )。
A.直接插入 B. 二分法插入 C. 快速排序 D. 歸並排序
15.在下列排序算法中,哪一個算法的時間復雜度與初始排序無關(D )。
A. 直接插入排序 B. 氣泡排序 C. 快速排序 D. 直接選擇排序
16.比較次數與排序的初始狀態無關的排序方法是( D )。
A.直接插入排序 B.起泡排序 C.快速排序 D.簡單選擇排序
17.數據序列(8,9,10,4,5,6,20,1,2)只能是下列排序算法中的( C )的兩趟排序后的結果。
A.選擇排序 B.冒泡排序 C.插入排序 D.堆排序
18.數據序列(2,1,4,9,8,10,6,20)只能是下列排序算法中的( A )的兩趟排序后的結果。
A. 快速排序 B. 冒泡排序 C. 選擇排序 D. 插入排序
19.對一組數據(84,47,25,15,21)排序,數據的排列次序在排序的過程中的變化為
(1) 84 47 25 15 21 (2) 15 47 25 84 21 (3) 15 21 25 84 47 (4) 15 21 25 47 84
則采用的排序是( A )。
A. 選擇 B. 冒泡 C. 快速 D. 插入
20.對序列{15,9,7,8,20,-1,4}進行排序,進行一趟后數據的排列變為{4,9,-1,8,20,7,15};則采用的是( C )排序。
A. 選擇 B. 快速 C. 希爾 D. 冒泡
21.若上題的數據經一趟排序后的排列為{9,15,7,8,20,-1,4},則采用的是(C )排序。
A.選擇 B. 堆 C. 直接插入 D. 冒泡
22.下列排序算法中( B )不能保證每趟排序至少能將一個元素放到其最終的位置上。
A.快速排序 B. shell排序 C. 堆排序 D.冒泡排序
23.下列排序算法中( C )排序在一趟結束后不一定能選出一個元素放在其最終位置上。
A. 選擇 B. 冒泡 C. 歸並 D. 堆
24.下列序列中,( C)是執行第一趟快速排序后所得的序列。
A. [68,11,18,69] [23,93,73] B. [68,11,69,23] [18,93,73]
C. [93,73] [68,11,69,23,18] D. [68,11,69,23,18] [93,73]
25.有一組數據(15,9,7,8,20,-1,7,4) 用快速排序的划分方法進行一趟划分后數據的排序為 ( A )(按遞增序)。
A.下面的B,C,D都不對。 B.9,7,8,4,-1,7,15,20
C.20,15,8,9,7,-1,4,7 D. 9,4,7,8,7,-1,15,20
26.一組記錄的關鍵碼為(46,79,56,38,40,84),則利用快速排序的方法,以第一個記錄為基准得到的一次划分結果為( C )。
A.(38,40,46,56,79,84) B. (40,38,46,79,56,84)
C.(40,38,46,56,79,84) D. (40,38,46,84,56,79)
27. 在下面的排序方法中,輔助空間為O(n)的是( D ) 。
A.希爾排序 B. 堆排序 C. 選擇排序 D. 歸並排序
28.下列排序算法中,在待排序數據已有序時,花費時間反而最多的是( C )排序。
A. 冒泡 B. 希爾 C. 快速 D. 堆
29.下列排序算法中,在每一趟都能選出一個元素放到其最終位置上,並且其時間性能受數據初始特性影響的是:( B )。
A. 直接插入排序 B. 快速排序 C. 直接選擇排序 D. 堆排序
30. 對初始狀態為遞增序列的表按遞增順序排序,最省時間的是( c )算法,最費時間的是( b )算法。
A. 堆排序 B. 快速排序 C. 插入排序 D. 歸並排序
31. 就平均性能而言,目前最好的內排序方法是( D )排序法。
A. 冒泡 B. 希爾插入 C. 交換 D. 快速
32.如果只想得到1000個元素組成的序列中第5個最小元素之前的部分排序的序列,用( D)方法最快。
A.起泡排序 B.快速排列 C.Shell排序 D.堆排序 E.簡單選擇排序
33.在文件“局部有序”或文件長度較小的情況下,最佳內部排序的方法是(A )
A.直接插入排序 B.冒泡排序 C.簡單選擇排序
34.下列排序算法中,( D )算法可能會出現下面情況:在最后一趟開始之前,所有元素都不在其最終的位置上。
A. 堆排序 B. 冒泡排序 C. 快速排序 D. 插入排序
35. 下列排序算法中,占用輔助空間最多的是:( A )
A. 歸並排序 B. 快速排序 C. 希爾排序 D. 堆排序
36.從未排序序列中依次取出一個元素與已排序序列中的元素依次進行比較,然后將其放在已排序序列的合適位置,該排序方法稱為( A)排序法。
A. 插入 B. 選擇 C. 希爾 D. 二路歸並
37. 在排序算法中,每次從未排序的記錄中挑出最小(或最大)關鍵碼字的記錄,加入到已排序記錄的末尾,該排序方法是( A )。
A. 選擇 B. 冒泡 C. 插入 D. 堆
38.用直接插入排序方法對下面四個序列進行排序(由小到大),元素比較次數最少的是( C )。
A. 94,32,40,90,80,46,21,69 B.32,40,21,46,69,94,90,80
C. 21,32,46,40,80,69,90,94 D.90,69,80,46,21,32,94,40
39.直接插入排序在最好情況下的時間復雜度為( B )
A.O(logn) B.O(n) C.O(n*logn) D.O(n2)
40. 若用冒泡排序方法對序列{10,14,26,29,41,52}從大到小排序,需進行 ( C )次比較。
A. 3 B. 10 C. 15 D. 25
41. 采用簡單選擇排序,比較次數與移動次數分別為( C )。
A. O(n),O(logn) B.O(logn),0(n*n) C. 0(n*n),0(n) D. 0(nlogn),0(n)
42. 對序列{15,9,7,8,20,-1,4,} 用希爾排序方法排序,經一趟后序列變為{15,-l,4,8,20,9,7}則該次采用的增量是 ( B )
A. l B. 4 C. 3 D. 2
43.對下列關鍵字序列用快速排序法進行排序時,速度最快的情形是( A )。
A. {21,25,5,17,9,23,30} B.{25,23,30,17,21,5,9}
C. {21,9,17,30,25,23,5} D.{5,9,17,21,23,25,30}
44.對關鍵碼序列28,16,32,12,60,2,5,72快速排序,從小到大一次划分結果為(B )。
A. (2,5,12,16)26(60,32,72) B. (5,16,2,12)28(60,32,72)
C. (2,16,12,5)28(60,32,72) D. (5,16,2,12)28(32,60,72)
45.對n個記錄的線性表進行快速排序為減少算法的遞歸深度,以下敘述正確的是( A )
A.每次分區后,先處理較短的部分 B.每次分區后,先處理較長的部分
C.與算法每次分區后的處理順序無關 D.以上三者都不對
46.當n個整型數據是有序時,對這n個數據用快速排序算法排序,則時間復雜度是 ( 6 ),當用遞歸算法求n!時,算法的時間復雜度是 ( 7 ),則:(6)-(7)=(C )
A. O(n) B. O(nlogn) C. O(n*n) D. O(logn)
47.快速排序在最壞情況下的時間復雜度是( B ),比( D )的性能差。
A.O(NlogN) B.O(N2) C.O(N3) D.堆排序E.冒泡排序F.選擇排序
48. 快速排序方法在( D )情況下最不利於發揮其長處。
A. 要排序的數據量太大 B. 要排序的數據中含有多個相同值
C. 要排序的數據個數為奇數 D. 要排序的數據已基本有序
49.在含有n個關鍵字的小根堆(堆頂元素最小)中,關鍵字最大的記錄有可能存儲在(D )位置上。
A.ën/2û B.ën/2û -1 C.1 D.ën/2û +2
50. 以下序列不是堆的是( D )。
A.(100,85,98,77,80,60,82,40,20,10,66) B.(100,98,85,82,80,77,66,60,40,20,10)
C.(10,20,40,60,66,77,80,82,85,98,100) D.(100,85,40,77,80,60,66,98,82,10,20)
51.下列四個序列中,哪一個是堆(C )。
A.75,65,30,15,25,45,20,10 B.75,65,45,10,30,25,20,15
C.75,45,65,30,15,25,20,10 D.75,45,65,10,25,30,20,15
52. 堆排序是(E )類排序,堆排序平均執行的時間復雜度和需要附加的存儲空間復雜度分別是(G)
A. 插入 B. 交換 C. 歸並 D. 基數 E. 選擇
F. O(n2)和O(1) G. O(nlog2n)和O(1)
H. O(nlog2n)和O(n) I. O(n2)和O(n)
53.在對n個元素的序列進行排序時,堆排序所需要的附加存儲空間是( B )。
A. O(log2n) B. O(1) C. O(n) D. O(nlog2n)
54. 對n 個記錄的文件進行堆排序,最壞情況下的執行時間是多少?( C )
A.O(log2n)B.O(n) C.O(nlog2n) D.O(n*n)
55. 有一組數據(15,9,7,8,20,-1,7,4),用堆排序的篩選方法建立的初始堆為 ( C )
A.-1,4,8,9,20,7,15,7 B.-1,7,15,7,4,8,20,9
C.-1,4,7,8,20,15,7,9 D.A,B,C均不對。
56. 歸並排序中,歸並的趟數是( B )。
A.O(n) B.O(logn) C.O(nlogn) D.O(n*n)
57. 在排序算法中每一項都與其它各項進行比較,計算出小於該項的項的個數,以確定該項的位置叫( B )
A.插入排序 B.枚舉排序 C.選擇排序 D.交換排序
58.就排序算法所用的輔助空間而言,堆排序,快速排序,歸並排序的關系是 (A )
A.堆排序〈 快速排序〈歸並排序 B.堆排序〈 歸並排序〈快速排序
C.堆排序〉 歸並排序 〉快速排序 D.堆排序 > 快速排序 > 歸並排序
E.以上答案都不對
59.排序方法有許多種,(1)法從未排序的序列中依次取出元素,與已排序序列(初始時為空)中的元素作比較,將其放入已排序序列的正確位置上;(2)法從未排序的序列中挑選元素,並將其依次放入已排序序列(初始時為空)的一端; 交換排序方法是對序列中的元素進行一系列比較,當被比較的兩元素逆序時,進行交換;(3)和(4)是基於這類方法的兩種排序方法, 而(4)是比(3)效率更高的方法;(5)法是基於選擇排序的一種排序方法,是完全二叉樹結構的一個重要應用。 CADBG
(1)--(5): A.選擇排序 B.快速排序 C.插入排序 D.起泡排序
E.歸並排序 F.shell排序 G.堆排序 H.基數排序
二、填空題
1.若不考慮基數排序,則在排序過程中,主要進行的兩種基本操作是關鍵字的__比較____和記錄的___移動__。
2. 外排序的基本操作過程是__生成有序歸並段_____和_歸並______。
3. 屬於不穩定排序的有_希爾排序、簡單選擇排序、快速排序、堆排序_________。
4.分別采用堆排序,快速排序,冒泡排序和歸並排序,對初態為有序的表,則最省時間的是__冒泡___算法,最費時間的是___快速___算法。
5. 不受待排序初始序列的影響,時間復雜度為O(N2)的排序算法是_簡單選擇排序____,在排序算法的最后一趟開始之前,所有元素都可能不在其最終位置上的排序算法是__直接插入排序___。
6.直接插入排序用監視哨的作用是__免去查找過程中每一步都要檢測整個表是否查找完畢,提高了查找效_____。
7.對n個記錄的表r[1..n]進行簡單選擇排序,所需進行的關鍵字間的比較次數為__ n(n-1)/2_____。
8. 設用希爾排序對數組{98,36,-9,0,47,23,1,8,10,7}進行排序,給出的步長(也稱增量序列)依次是4,2,1則排序需______3____趟,寫出第一趟結束后,數組中數據的排列次序_ (10,7,-9,0,47,23,1,8,98,36)________。
9.從平均時間性能而言,____快速______排序最佳。
10.對於7個元素的集合{1,2,3,4,5,6,7}進行快速排序,具有最小比較和交換次數的初始排列次序為_ (4,1,3,2,6,5,7)____。
11.快速排序在_每次划分能得到兩個等長的子序列____的情況下最易發揮其長處。
12.在數據表有序時,快速排序算法的時間復雜度是__ O(n2)__。
13.堆排序的算法時間復雜度為:_ O(nlog2n)____。
三、應用題
1. 在堆排序、快速排序和合並排序中:
(1).若只從存儲空間考慮,則應首先選取哪種排序方法,其次選取哪種排序方法,最后選取哪種排序方法?
(2).若只從排序結果的穩定性考慮,則應選取哪種排序方法?
(3).若只從平均情況下排序最快考慮,則應選取哪種排序方法?
(4).若只從最壞情況下排序最快並且要節省內存考慮,則應選取哪種排序方法?
(1)堆排序,快速排序,歸並排序(2)歸並排序 (3)快速排序 (4)堆排序
2. 快排序、堆排序、合並排序、Shell排序中哪種排序平均比較次數最少,哪種排序占用空間最多,哪幾種排序算法是不穩定的?
平均比較次數最少: 快速排序; 占用空間最多: 歸並排序; 不穩定排序算法:快速排序、堆排序、希爾排序。
3.算法模擬
設待排序的記錄共7個,排序碼分別為8,3,2,5,9,1,6。
(1) 用直接插入排序。試以排序碼序列的變化描述形式說明排序全過程(動態過程)要求按遞減順序排序。
(2) 用直接選擇排序。試以排序碼序列的變化描述形式說明排序全過程(動態過程)要求按遞減順序排序。
(3) 直接插入排序算法和直接選擇排序算法的穩定性如何?
(1)直接插入排序
第一趟 (3)[8,3],2,5,9,1,6
第二趟 (2)[8,3,2],5,9,1,6
第三趟 (5)[8,5,3,2],9,1,6
第四趟 (9)[9,8,5,3,2],1,6
第五趟 (1)[9,8,5,3,2,1],6
第六趟 (6)[9,8,6,5,3,2,1]
(2)直接選擇排序(第六趟后僅剩一個元素,是最小的,直接選擇排序結束)
第一趟 (9)[9],3,2,5,8,1,6
第二趟 (8)[9,8],2,5,3,1,6
第三趟 (6)[9,8,6],5,3,1,2
第四趟 (5)[9,8,6,5],3,1,2
第五趟 (3)[9,8,6,5,3],1,2
第六趟 (2)[9,8,6,5,3,2],1
(3)直接插入排序是穩定排序,直接選擇排序是不穩定排序。
4.對給定文件(28,07,39,10,65,14,61,17,50,21)選擇第一個元素28進行划分,寫出其快速排序第一遍的排序過程。
初始序列:[28],07,39,10,65,14,61,17,50,21
21移動:21,07,39,10,65,14,61,17,50,[]
39移動:21,07,[],10,65,14,61,17,50,39
17移動:21,07,17,10,65,14,61,[],50,39
65移動:21,07,17,10,[],14,61,65,50,39
14移動:21,07,17,10,14,[28],61,65,50,39
5.已知一關鍵碼序列為:3,87,12,61,70,97,26,45。試根據堆排序原理,填寫完整下示各步驟結果。
建立堆結構:__ :97,87,26,61,70,12,3,45___________
交換與調整:
(1)87 70 26 61 45 12 3 97;
(2)______ 70,61,26,3,45,12,87,97______________;
(3)61 45 26 3 12 70 87 97;
(4)_______ 45,12,26,3,61,70,87,97_____________;
(5)26 12 3 45 61 70 87 97;
(6)_______ 12,3,26,45,61,70,87,97_____________;
(7)3 12 26 45 61 70 87 97;
6.全國有10000人參加物理競賽,只錄取成績優異的前10名,並將他們從高分到低分輸出。而對落選的其他考生,不需排出名次,問此種情況下,用何種排序方法速度最快?為什么?
堆排序
在內部排序方法中,一趟排序后只有簡單選擇排序和冒泡排序可以選出一個最大(或最小)元素,並加入到已有的有序子序列中,但要比較n-1次。選次大元素要再比較n-2次,其時間復雜度是O(n2)。從10000個元素中選10個元素不能使用這種方法。而快速排序、插入排序、歸並排序、基數排序等時間性能好的排序,都要等到最后才能確定各元素位置。只有堆排序,在未結束全部排序前,可以有部分排序結果。建立堆后,堆頂元素就是最大(或最小,視大堆或小堆而定)元素,然后,調堆又選出次大(小)元素。凡要求在n個元素中選出k(k<<n,k>2)
個最大(或最小)元素,一般均使用堆排序。因為堆排序建堆比較次數至多不超過4n,對深度為k的堆,在調堆算法中進行的關鍵字的比較次數至多為2(k-1)次,且輔助空間為O(1)。
7. 給出一組關鍵字:29,18,25,47,58,12,51,10,分別寫出按下列各種排序方法進行排序時的變化過程:
(1) 歸並排序 每歸並一次書寫一個次序。
(2) 快速排序 每划分一次書寫一個次序。
(3) 堆排序 先建成一個堆,然后每從堆頂取下一個元素后,將堆調整一次。
(1)2路歸並
第一趟:18,29,25,47,12,58,10,51;
第二趟:18,25,29,47,10,12,51,58;
第三趟:10,12,18,25,29,47,51,58
(2)快速排序
第一趟:10,18,25,12,29,58,51,47;
第二趟:10,18,25,12,29,47,51,88;
第三趟:10,12,18,25,29,47,51,88
(3)堆排序 建大堆
58,47,51,29,18,12,25,10;
①51,47,25,29,18,12,10,58;
②47,29,25,10,18,12,51,58;
③29,18,25,10,12,47,51,58;
④25,18,12,10,29,47,51,58;
⑤18,10,12,25,29,47,51,58;
⑥12,10,18,25,29,47,51,58;
⑦10,12,18,25,29,47,51,58
8.請寫出應填入下列敘述中( )內的正確答案。
排序有各種方法,如插入排序、快速排序、堆排序等。
設一數組中原有數據如下:15,13,20,18,12,60。下面是一組由不同排序方法進行一遍排序后的結果。
(快速 )排序的結果為:12,13,15,18,20,60
( 冒泡)排序的結果為:13,15,18,12,20,60
(直接插入 )排序的結果為:13,15,20,18,12,60
( 堆)排序的結果為:12,13,20,18,15,60
五、算法設計題:
1.冒泡排序算法是把大的元素向上移(氣泡的上浮),也可以把小的元素向下移(氣泡的下沉)請給出上浮和下沉過程交替的冒泡排序算法。
void BubbleSort2(int a[],int n) //相鄰兩趟向相反方向起泡的冒泡排序算法
{ change=1;low=0;high=n-1; //冒泡的上下界
while(low<high && change)
{ change=0; //設不發生交換
for(i=low;i<high;i++) //從上向下起泡
if(a[i]>a[i+1]){a[i]<-->a[i+1];change=1;} //有交換,修改標志change
high--; //修改上界
for(i=high;i>low;i--) //從下向上起泡
if(a[i]<a[i-1]){a[i]<-->a[i-1];change=1;}
low++; //修改下界
}//while
}//BubbleSort2
2.寫出一趟快速排序算法。
int Partition(RecType R[],int l,int h)
//一趟快速排序算法,樞軸記錄到位,並返回其所在位置,
{ int i=l; j=h; R[0] = R[i]; x =R[i].key;
while(i<j)
{ while(i<j && R[j].key>=x) j--;
if (i<j) R[i] = R[j];
while(i<j && R[i].key<=x) i++;
if (i<j) R[j] = R[i];
}//while
R[i]=R[0];
return i;
3.非遞歸的快速排序算法。
void QuickSort(rectype r[n+1]; int n)
// 對r[1..n]進行快速排序的非遞歸算法
{typedef struct
{ int low,high; }node
node s[n+1];//棧,容量足夠大
int quickpass(rectype r[],int,int); // 函數聲明
int top=1; s[top].low=1; s[top].high=n;
while (top>0)
{ss=s[top].low; tt=s[top].high; top--;
if (ss<tt)
{k=quickpass(r,ss,tt);
if (k-ss>1) {s[++top].low=ss; s[top].high=k-1;}
if (tt-k>1) {s[++top].low=k+1; s[top].high=tt;}
}
} // 算法結束
int quickpass(rectype r[];int s,t)
{i=s; j=t; rp=r[i]; x=r[i].key;
while (i<j)
{while (i<j && x<=r[j].key) j--;
if (i<j) r[i++]=r[j];
while (i<j && x>=r[j].key) i++;
if (i<j) r[j--]=r[i];;
]
r[i]=rp;
return (i);
} // 一次划分算法結束
