給定N個(長整型範圍內的)整數,要求輸出從小到大排序後的結果。
本題旨在測試各種不同的排序算法在各種數據情況下的表現。各組測試數據特點如下:
數據1:只有1個元素;
數據2:11個不相同的整數,測試基本正確性;
數據3:103個隨機整數;
數據4:104個隨機整數;
數據5:105個隨機整數;
數據6:105個順序整數;
數據7:105個逆序整數;
數據8:105個基本有序的整數;
數據9:105個隨機正整數,每個數字不超過1000。
輸入格式:
輸入第一行給出正整數N(≤105),隨後一行給出N個(長整型範圍內的)整數,其間以空格分隔。
輸出格式:
在一行中輸出從小到大排序後的結果,數字間以1個空格分隔,行末不得有多餘空格。
輸入樣例:
11
4 981 10 -17 0 -20 29 50 8 43 -5
輸出樣例:
-20 -17 -5 0 4 8 10 29 43 50 981
#include<stdio.h> #include<stdlib.h> #include<algorithm> #define MAX 100000 using namespace std; void Swap(int *a,int *b) { int t; t = *a; *a = *b; *b = t; } void print(int A[],int N) { for(int i = 0; i < N; i++) { printf("%d",A[i]); if(i < N - 1) { printf(" "); } } printf("\n"); } /*冒泡排序*/ void maopao_sort(int A[],int N) { int p,flag; for(p = N - 1; p >= 0; p--) { flag = 0; for(int i = 0; i < p; i++) { if(A[i] > A[i + 1]) { Swap(&A[i],&A[i + 1]); flag = 1; } } if(flag == 0)break; } print(A,N); } /*插入排序*/ void Insert_sort(int A[],int N) { int p,Tmp; for(int i = 1; i < N; i++) { Tmp = A[i]; for(p = i; p > 0 && A[p - 1] > Tmp; p--) { A[p] = A[p - 1];/*將大的一個一個向後推*/ } A[p] = Tmp;/*最後放到合適的位置*/ } print(A,N); } /*希爾排序*/ void shell_sort(int A[],int N) { int p,Tmp,d,si,i; int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0}; for(int si = 0; Sedgewick[si] >= N; si++);/*初始增量Sedgewick[si]不能超過序列長度(N)*/ for(d = Sedgewick[si]; d > 0; d = Sedgewick[++si]) { for(i = d; i < N; i++)/*在數組A中,從下標爲d開始往後掃描*/ { Tmp = A[i]; for(p = i; p >= d && A[p - d] > Tmp; p -= d)/*每次判斷A[p - d] 與 A[p]的大小關係,當p < d時說明A[p]前沒有d那麼多個數了*/ { A[p] = A[p - d]; } A[p] = Tmp; } } print(A,N); } /*堆排序*/ void percDown(int A[],int p,int N)/*構建最大堆,因爲再後面要將數組第一個元素與最後一個互換,所以再輸出的時候就是從小到大輸出的*/ { int child,parent; int X; X = A[p]; for(parent = p; (parent * 2) + 1 < N; parent = child) { child = parent * 2 + 1; if(child != N - 1 && A[child] < A[child + 1]) { child++; } if(X >= A[child]) break; else { A[parent] = A[child]; } } A[parent] = X; } void Heap_sort(int A[],int N) { for(int i = (N - 1)/2 ; i >= 0; i--) { percDown(A,i,N); } for(int i = N - 1; i > 0; i--) { Swap(&A[0],&A[i]);/*交換後數組A的最後一位就是最大值,並且下次循環的時候不會將最後一位進入percDown函數*/ percDown(A,0,i); } print(A,N); } /*歸併排序*/ void Merge(int A[],int TmpA[],int L,int R,int Rightend)/* L = 左邊起始位置, R = 右邊起始位置, RightEnd = 右邊終點位置*/ { int num,Leftend; Leftend = R - 1; int Tmp = L; num = Rightend - L + 1; while(L <= Leftend && R <= Rightend) { if(A[L] >= A[R]) { TmpA[Tmp++] = A[R++]; } else { TmpA[Tmp++] = A[L++]; } } while(L <= Leftend) TmpA[Tmp++] = A[L++]; while(R <= Rightend) TmpA[Tmp++] = A[R++]; for(int i = 0; i < num; i++, Rightend--) { A[Rightend] = TmpA[Rightend];/*從後往前賦給A數組*/ } } void Msort(int A[],int TmpA[],int L,int Rightend) { int mid; if(L < Rightend) { mid = (L + Rightend)/2; Msort(A,TmpA,L,mid); Msort(A,TmpA,mid + 1,Rightend); Merge(A,TmpA,L,mid + 1,Rightend); } } void MergeSort(int A[],int N)/*遞歸方法*/ { int *TmpA = (int *)malloc(N * sizeof(int)); if(TmpA != NULL) { Msort(A,TmpA,0,N - 1); free(TmpA); } else { printf("空間不足"); } print(A,N); } void Merge_pass(int A[],int TmpA[],int length,int N)/*循環實現*/ { int i,j; for(i = 0 ; i <= N - length*2; i += length*2) { Merge(A, TmpA, i, i + length, i + length*2 - 1); } if ( i+length < N ) /* 歸併最後2個子列*/ Merge( A, TmpA, i, i+length, N-1); else /* 最後只剩1個子列*/ for ( j = i; j < N; j++ ) TmpA[j] = A[j]; } void Merge_Sort(int A[],int N) { int length = 1; int *TmpA = (int *)malloc(N * sizeof(int)); if(TmpA != NULL) { while(length < N) { Merge_pass(A,TmpA,length,N); length *= 2; Merge_pass(TmpA,A,length,N); length *= 2; } free(TmpA); } else { printf("空間不足"); } print(A,N); } int main(void) { int N; int A[MAX]; scanf("%d",&N); for(int i = 0; i < N; i++) { scanf("%d",&A[i]); } // maopao_sort(A,N);/*冒泡排序*/ // Insert_sort(A,N);/*插入排序*/ // shell_sort(A,N);/*希爾排序*/ // Heap_sort(A,N);/*堆排序*/ // MergeSort(A,N);/*歸併排序 - 遞歸方法*/ Merge_Sort(A,N);/*歸併排序 - 循環實現*/ return 0; }