给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。
本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:
数据1:只有1个元素;
数据2:11个不相同的整数,测试基本正确性;
数据3:103个随机整数;
数据4:104个随机整数;
数据5:105个随机整数;
数据6:105个顺序整数;
数据7:105个逆序整数;
数据8:105个基本有序的整数;
数据9:105个随机正整数,每个数字不超过1000。
输入格式:
输入第一行给出正整数N(≤10^5),随后一行给出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
总结:
1.冒泡排序 插入排序 运行时间长,冒泡排序有运行超时。其他排序算法 运行时间差不多
2.希尔排序 堆排序 不稳定
3.归并排序 稳定 但需要额外开辟空间
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <stdlib.h> 3 typedef int ElementType; 4 5 6 void BubbleSort(ElementType A[], int N) 7 { 8 for(int P = N-1; P >= 0; P--) { 9 int flag = 0; 10 for(int i = 0; i < P; i++) { 11 if( A[i] > A[i+1] ) { 12 ElementType temp = A[i]; //swap A[i] A[i+1] 13 A[i] = A[i+1]; 14 A[i+1] = temp; 15 flag = 1; 16 } 17 } 18 if(flag == 0) 19 break; 20 } 21 } 22 23 void InsertionSort(ElementType A[], int N) 24 { 25 int i; 26 for (int P = 1; P < N; P++ ) { 27 ElementType temp = A[P]; //取出未排序序列中的第一个元素 28 for (i = P; i > 0 && A[i-1] > temp; i-- ) 29 A[i] = A[i-1]; //依次与已排序序列中元素比较并右移 30 A[i] = temp; 31 } 32 } 33 34 /* 原始希尔排序 */ 35 void Shell_Sort(ElementType A[], int N) 36 { 37 int i; 38 for(int D = N/2; D > 0; D/=2) { 39 for(int P = D; P < N; P++) { 40 ElementType temp = A[P]; 41 for(i = P; i >= D && A[i-D]>temp; i-=D) 42 A[i] = A[i-D]; 43 A[i] = temp; 44 } 45 } 46 } 47 48 /* 希尔排序 - 用Sedgewick增量序列 */ 49 void ShellSort(ElementType A[], int N) 50 { 51 int Si, i; 52 /* 这里只列出一小部分增量 */ 53 int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0}; 54 55 for ( Si = 0; Sedgewick[Si] >= N; Si++ ) 56 ; /* 初始的增量Sedgewick[Si]不能超过待排序列长度 */ 57 58 for (int D = Sedgewick[Si]; D > 0; D = Sedgewick[++Si]) 59 for (int P = D; P < N; P++ ) { //插入排序 60 ElementType temp = A[P]; 61 for(i = P; i >= D && A[i-D]>temp; i-=D) 62 A[i] = A[i-D]; 63 A[i] = temp; 64 } 65 } 66 67 void Swap( ElementType *a, ElementType *b ) 68 { 69 ElementType t = *a; 70 *a = *b; 71 *b = t; 72 } 73 /* 改编PercDown( MaxHeap H, int p )*/ 74 void PercDown( ElementType A[], int p, int N ) 75 { 76 /* 将N个元素的数组中以A[p]为根的子堆调整为最大堆 */ 77 int Parent, Child; 78 79 ElementType X = A[p]; /* 取出根结点存放的值 */ 80 for( Parent=p; (Parent*2+1) < N; Parent=Child ) { 81 Child = Parent * 2 + 1; 82 if( (Child != N-1) && (A[Child] < A[Child+1]) ) 83 Child++; /* Child指向左右子结点的较大者 */ 84 if( X >= A[Child] ) break; /* 找到了合适位置 */ 85 else /* 下滤X */ 86 A[Parent] = A[Child]; 87 } 88 A[Parent] = X; 89 } 90 91 void HeapSort(ElementType A[], int N) 92 { 93 for(int i = N/2-1; i >= 0; i--)/* 建立最大堆 */ 94 PercDown( A, i, N ); 95 96 for(int i = N-1; i > 0; i--) { 97 /* 删除最大堆顶 */ 98 Swap(&A[0], &A[i] ); 99 PercDown(A, 0, i); 100 } 101 } 102 103 /* 归并排序 - 递归实现 */ 104 105 /* L = 左边起始位置, R = 右边起始位置, RightEnd = 右边终点位置*/ 106 void Merge( ElementType A[], ElementType TmpA[], int L, int R, int RightEnd ) 107 { /* 将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列 */ 108 109 int LeftEnd = R - 1; /* 左边终点位置 */ 110 int temp = L; /* 有序序列的起始位置 */ 111 int NumElements = RightEnd - L + 1; 112 113 while( L <= LeftEnd && R <= RightEnd ) { 114 if ( A[L] <= A[R] ) 115 TmpA[temp++] = A[L++]; /* 将左边元素复制到TmpA */ 116 else 117 TmpA[temp++] = A[R++]; /* 将右边元素复制到TmpA */ 118 } 119 120 while( L <= LeftEnd ) 121 TmpA[temp++] = A[L++]; /* 直接复制左边剩下的 */ 122 while( R <= RightEnd ) 123 TmpA[temp++] = A[R++]; /* 直接复制右边剩下的 */ 124 125 for(int i = 0; i < NumElements; i++, RightEnd -- ) 126 A[RightEnd] = TmpA[RightEnd]; /* 将有序的TmpA[]复制回A[] */ 127 } 128 /* 核心递归排序函数 */ 129 void Msort( ElementType A[], ElementType TmpA[], int L, int RightEnd ) 130 { 131 int Center; 132 133 if ( L < RightEnd ) { 134 Center = (L+RightEnd) / 2; 135 Msort( A, TmpA, L, Center ); /* 递归解决左边 */ 136 Msort( A, TmpA, Center+1, RightEnd ); /* 递归解决右边 */ 137 Merge( A, TmpA, L, Center+1, RightEnd ); /* 合并两段有序序列 */ 138 } 139 } 140 /* 归并排序接口函数 */ 141 void MergeSort( ElementType A[], int N ) 142 { 143 ElementType *TmpA; 144 TmpA = (ElementType *)malloc(N*sizeof(ElementType)); 145 146 if ( TmpA != NULL ) { 147 Msort( A, TmpA, 0, N-1 ); 148 free( TmpA ); 149 } 150 else printf( "空间不足" ); 151 } 152 153 /* 归并排序 - 循环实现 */ 154 155 /* 这里Merge函数在递归版本中给出 */ 156 /* length = 当前有序子列的长度*/ 157 void Merge_pass( ElementType A[], ElementType TmpA[], int N, int length ) 158 { /* 两两归并相邻有序子列 */ 159 int i, j; 160 161 for ( i = 0; i <= N-2*length; i += 2*length ) 162 Merge( A, TmpA, i, i+length, i+2*length-1 ); 163 if ( i+length < N ) /* 归并最后2个子列*/ 164 Merge( A, TmpA, i, i+length, N-1); 165 else /* 最后只剩1个子列*/ 166 for ( j = i; j < N; j++ ) TmpA[j] = A[j]; 167 } 168 169 void Merge_Sort( ElementType A[], int N ) 170 { 171 int length; 172 ElementType *TmpA; 173 174 length = 1; /* 初始化子序列长度*/ 175 TmpA = (ElementType *)malloc( N * sizeof( ElementType ) ); 176 if ( TmpA != NULL ) { 177 while( length < N ) { 178 Merge_pass( A, TmpA, N, length ); 179 length *= 2; 180 Merge_pass( TmpA, A, N, length ); 181 length *= 2; 182 } 183 free( TmpA ); 184 } 185 else printf( "空间不足" ); 186 } 187 188 189 190 int main() 191 { 192 int N; 193 int a[100005]; 194 scanf("%d",&N); 195 for(int i = 0; i < N; i++) 196 scanf("%d",&a[i]); 197 // BubbleSort(a,N); 198 // InsertionSort(a,N); 199 // Shell_Sort(a,N); 200 // ShellSort(a,N); //希尔排序 - 用Sedgewick增量序列 201 // HeapSort(a,N); 202 // MergeSort(a,N); //归并排序 - 递归实现 203 // Merge_Sort(a,N); 204 for(int i = 0; i < N-1; i++) 205 printf("%d ",a[i]); 206 printf("%d\n",a[N-1]); 207 return 0; 208 }