判斷題
1.希爾排序是穩定的算法。
穩定的算法:保證排序前兩個相等的數其在序列的前后位置順序和排序后它們兩個的前后位置順序相同。
希爾排序會多次進行插入排序,一次插入排序是穩定的,但是因為希爾排序每次插入排序選擇的步長不一樣,導致希爾排序不穩定。
2.僅基於比較的算法能得到的最好的“最壞時間復雜度”是O(NlogN)。
僅基於比較的算法能得到的最好的“最好時間復雜度”是O(N),僅基於比較的算法能得到的最好的“最壞時間復雜度”是O(NlogN)。
3.(neuDS)直接插入排序算法在最好情況下的時間復雜度為O(n)。
4.內排序要求數據一定要以順序方式存儲。
內排序是完全在內存中存放待排序元素的排序,存儲形式不一定是順序的。
5.排序算法中的比較次數與初始元素序列的排列無關。
6.排序的穩定性是指排序算法中的比較次數保持不變,且算法能夠終止。
7.對N個記錄進行堆排序,需要的額外空間為O(N)。
不需要額外的空間。
8.堆排序是穩定的排序算法。( )
9.在堆排序中,若要進行升序排序,則需要建立大根堆。( )
10.對N個記錄進行快速排序,在最壞的情況下,其時間復雜度是O(NlogN)。
11.在初始數據表已經有序時,快速排序算法的時間復雜度為O(nlogn )
快速排序的時間復雜度和是否有序無關。
12.當待排序記錄已經從小到大排序或者已經從大到小排序時,快速排序的執行時間最省。
13.快速排序的速度在所有排序方法中為最快,而且所需附加空間也最少。
選擇題
1.下列排序算法中,哪種算法可能出現:在最后一趟開始之前,所有的元素都不在其最終的位置上?(設待排元素個數N>2)
B.插入排序
C.堆排序
D.快速排序
2.對初始數據序列{ 8, 3, 9, 11, 2, 1, 4, 7, 5, 10, 6 }進行希爾排序。若第一趟排序結果為( 1, 3, 7, 5, 2, 6, 4, 9, 11, 10, 8 ),第二趟排序結果為( 1, 2, 6, 4, 3, 7, 5, 8, 11, 10, 9 ),則兩趟排序采用的增量(間隔)依次是:
B.3, 2
C.5, 2
D.5, 3
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
first | 8 | 3 | 9 | 11 | 2 | 1 | 4 | 7 | 5 | 10 | 6 |
second | 1 | 3 | 7 | 5 | 2 | 6 | 4 | 9 | 11 | 10 | 8 |
紅色部分可以看出,第一次的增量是5。
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|
紅色部分可以看出,第二次的增量是3。
3.對關鍵字序列(56,23,78,92,88,67,19,34),進行增量為3的一趟希爾排序的結果為( )。
B.(23,56,78,66,88,92,19,34)
C.(19,23,34,56,67,78,88,92)
D.(19,23,67,56,34,78,92,88)
4.有組記錄的排序碼為{ 46,79,56,38,40,84 },則利用堆排序的方法建立的初始堆為:
B.84,79,56,46,40,38
C.84,56,79,40,46,38
D.84,79,56,38,40,46
5.對N個記錄進行堆排序,最壞的情況下時間復雜度是:
B.O(N)
C.O(NlogN)
D.O(N 2)
最壞的情況下,堆元素下濾都從頂部下濾到底部,為logN,一共N個元素,所以總的時間復雜度是O(NlogN)。
6.對N個記錄進行堆排序,需要的額外空間為:
B.O(logN)
C.O(N)
D.O(NlogN)
7.在含有n個關鍵字的小根堆中,關鍵字最大的記錄有可能存儲在()位置上。
B.1
C.n/2 -1
D.n/2
8.有一組數據(15,9,7,8,20,-1,7,4),用堆排序的篩選方法建立的初始堆為()。
B.-1,7,15,7,4,8,20,9
C.-1,4,7,8,20,15,7,9
D.A,B,C均不對。
9.下列關鍵字序列中,構成大根堆的是( )。
B.9,8,1,7,5,6,2,3
C.9,8,6,3,5,1,2,7
D.9,8,6,7,5,1,2,3
10.采用遞歸方式對順序表進行快速排序,下列關於遞歸次數的敘述中,正確的是:
B.每次划分后,先處理較短的分區可以減少遞歸次數
C.遞歸次數與每次划分后得到的分區處理順序無關
D.遞歸次數與初始數據的排列次序無關
11.對N個記錄進行快速排序,在最壞的情況下,其時間復雜度是:
B.O(NlogN)
C.O(N 2)
D.O(N 2logN)
12.在快速排序的一趟划分過程中,當遇到與基准數相等的元素時,如果左右指針都會停止移動,那么當所有元素都相等時,算法的時間復雜度是多少?
B.O(N)
C.O(NlogN)
D.O(N 2)
指針停止就會不斷交換左右指針的元素,這樣雖然多余的交換次數變多,但讓子序列的元素相對平均,所以一共有logN次划分,每次時間復雜度是O(N)。
13.在快速排序的一趟划分過程中,當遇到與基准數相等的元素時,如果左右指針都不停止移動,那么當所有元素都相等時,算法的時間復雜度是多少?
B.O(N)
C.O(NlogN)
D.O(N 2)
指針不停止,導致所有元素都被放到一個划分中去,一共N個元素,所以一共有N次划分,每次時間復雜度是O(N)。
14.執行一趟快速排序能夠得到的序列是( )。
B.[45,34,12,41] 55 [72,63,27]
C.[63,12,34,45,27] 55 [41,72]
D.[12,27,45,41] 55 [34,63,72]
15.有一組數據(15,9,7,8,20,-1,7,4) 用快速排序的划分方法進行一趟划分后數據的排序為 ( )(按遞增序)。
B.20,15,8,9,7,-1,4,7
C.9,4,7,8,7,-1,15,20
D.4,9,7,8,7,-1,15,20
16.有組記錄的排序碼為{46,79,56,38,40,84 },采用快速排序(按教材算法操作),以位於最左位置的對象為主元得到的第一次划分結果為:
B.{38,79,56,46,40,84}
C.{40,38,46,79,84,56}
D.{40,38,46,56,79,84}
17.用快速排序方法對線性表(25,84,21,47,15,27,68,35,20)進行排序時,以位於最左位置的對象為主元,得到的第一次划分結果為(按教材算法操作):
B.15,20,21,25,35,27,47,68,84
C.15,20,21,25,27,35,47,68,84
D.20,15,21,25,84,27,68,35,47
填空題
1.本題要求用冒泡排序將一組整數按增序排序。冒泡排序每次從頭到尾掃描待排序列,檢查相鄰兩數的順序,如果順序不對就交換。請補全下列冒泡排序的代碼。
typedef struct node *nodeptr; struct node{ int value; nodeptr next; /* 一些其他的項,在此忽略 */ }; nodeptr BubbleSort (nodeptr h) {/* h 是帶空頭結點的鏈表的頭指針 */ nodeptr p, q; int flag_swap; if (!h->next) return h; do{ flag_swap = 0; p = h; while (p->next->next){ if ( (3分) ){ flag_swap++; q = p->next; (3分); (3分); (3分); } else p = p->next; } } while (flag_swap > 0); return h; } |
2.下列代碼的功能是利用堆排序將N
個元素按非遞減順序排序。
#define leftchild(i) ( 2*(i)+1 ) void PercDown( ElementType A[], int i, int N ) { int child; ElementType Tmp; for ( Tmp = A[i]; leftchild(i) < N; i = child ) { child = leftchild(i); if ( (3分)) child ++; if ( (3分)) A[i] = A[child]; else break; } (3分); } void Heapsort( ElementType A[ ], int N ) { int i; for ( i = N / 2; i >= 0; i -- ) /* BuildHeap */ PercDown( A, i, N ); for ( i = N-1; i > 0; i -- ) { Swap( &A[ 0 ], &A[ i ] ); (3分); } } |
3.下列代碼的功能是將一列元素{ r[1] … r[n]
}按其鍵值 key
的非遞減順序排序。普通選擇排序是每次僅將一個待排序列的最小元放到正確的位置上,而這個另類的選擇排序是每次從待排序列中同時找到最小元和最大元,把它們放到最終的正確位置上。
void sort( list r[], int n ) { int i, j, mini, maxi; for (i=1; i<n-i+1; i++) { mini = maxi = i; for( j=i+1; (3分); ++j ){ if( (3分) ) mini = j; else if(r[j]->key > r[maxi]->key) maxi = j; } if( (3分) ) swap(&r[mini], &r[i]); if( maxi != n-i+1 ){ if( (3分) ) swap(&r[mini], &r[n-i+1]); else swap(&r[maxi], &r[n-i+1]); } } } |
4.本函數的功能是從有N
個元素的線性表A
中查找第K
小的元素。函數的初始調用為Qselect(A, K, 0, N-1)
。請完成下列填空。
ElementType Qselect( ElementType A[], int K, int Left, int Right ) { ElementType Pivot = A[Left]; int L = Left, R = Right+1; while (1) { while ( A[++L] < Pivot ) ; (3分); if ( L < R ) Swap( &A[L], &A[R] ); else break; } Swap( &A[Left], &A[R] ); if ( K < (L-Left) ) return Qselect(A, K, Left, R-1); else if ( K > (L-Left) ) (3分); else return Pivot; } |
5.本題要求實現快速排序操作,待排序列的長度1<=n<=1000。 使排序后的數據從小到大排列。
類型定義:
typedef int KeyType; typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩沖區*/ int Length; }SqList; |
程序:
#include<stdio.h> #include<stdlib.h> typedef int KeyType; typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩沖區*/ int Length; }SqList; void CreatSqList(SqList *L);/*待排序列建立,由裁判實現,細節不表*/ int Partition ( SqList L,int low, int high ); void Qsort ( SqList L,int low, int high ); int main() { SqList L; int i; CreatSqList(&L); Qsort(L,1,L.Length); for(i=1;i<=L.Length;i++) { printf("%d ",L.elem[i]); } return 0; } int Partition ( SqList L,int low, int high ) { /*一趟划分*/ KeyType pivotkey; L.elem[0] = L.elem[low]; pivotkey = L.elem[low]; while(low<high) { while ( low < high && L.elem[high] >= pivotkey ) --high; L.elem[low] = L.elem[high]; while ( low < high && L.elem[low] <= pivotkey ) ++low; L.elem[high] = L.elem[low]; } L.elem[low]=L.elem[0]; return low; } void Qsort ( SqList L,int low, int high ) { int pivotloc; if ( (2分) ) { pivotloc = Partition(L, low, high ) ; Qsort ( (2分)) ; (2分); } } |
輸入樣例:
第一行整數表示參與排序的關鍵字個數。第二行是關鍵字值 例如:
10 5 2 4 1 8 9 10 12 3 6 |
輸出樣例:
輸出由小到大的有序序列,每一個關鍵字之間由空格隔開,最后一個關鍵字后有一個空格。
1 2 3 4 5 6 8 9 10 12 |