给定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
结尾无空行
1.冒泡排序
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int ElementType;
void BubbleSort(ElementType a[],long N){
int i,j,temp;
bool flag;//flag标志整个序列是否已经有序
for(i=0;i<N-1;i++)//N-1趟冒泡
{
flag=true;
for(j=N-1;j>i;j--)//最小的元素下去
{
if(a[j]<a[j-1]){
temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
flag=false;
}
}
if(flag) break;
}
}
int main()
{
long N,i;
scanf("%ld",&N);
int a[N];
for(i=0;i<N;i++) scanf("%d",a+i);
BubbleSort(a,N);
bool IsFirst=true;
for(i=0;i<N;i++){
if(IsFirst==true){
printf("%d",a[i]);
IsFirst=false;
}else
printf(" %d",a[i]);
}
return 0;
}
2.插入排序
void InsertionSort(ElementType a[],long N){
int i,j;
ElementType X;
for(i=1;i<N;i++){
X=a[i];
for(j=i;j>0 && a[j-1]>X;j--){
a[j]=a[j-1];
}
a[j]=X;
}
}
3.希尔排序
1)普通增量序列
void ShellSort(ElementType a[],long N){
long D,i,j;
ElementType X;
for(D=N/2;D>0;D/=2){
for(i=D;i<N;i++){
X=a[i];
for(j=i;j>=D && a[j-D]>X;j-=D)
a[j]=a[j-D];
a[j]=X;
}
}
}
2)Sedgewick增量序列
void ShellSort(ElementType a[],long N){
long D,i,j;
ElementType X;
long Sedgewick[]={1, 5, 19, 41, 109, 209, 505, 929, 2161, 3905, 8929, 16001, 36289, 64769};
int k;
for(k=13;Sedgewick[k]>N;k--);
for(D=Sedgewick[k];k>=0;D=Sedgewick[--k]){
for(i=D;i<N;i++){
X=a[i];
for(j=i;j>=D && a[j-D]>X;j-=D)
a[j]=a[j-D];
a[j]=X;
}
}
}
4.堆排序
1)另建了一个堆,排好序后拷贝到原数组
#define CAPACITY 100000
typedef int ElementType;
/*先按结构特性放入数组树中,然后以每个有孩子节点的节点为根节点,进行“下滤”堆排序,(叶节点已经被视为一个堆),建堆为O(N)*/
typedef struct HNode * Heap;
struct HNode {
ElementType * Data;//数组
long Size;//堆中当前元素个数
long Capacity;//堆的最大容量
};
typedef Heap MaxHeap;
void PercDown(MaxHeap H,long i){
ElementType X=H->Data[i];
long child;
for(;2*i+1<=H->Size-1;i=child){
child=2*i+1;
if(child+1<=H->Size-1 && H->Data[child+1]>H->Data[child])
child++;
if(X>=H->Data[child]) break;
H->Data[i]=H->Data[child];
}
H->Data[i]=X;
}
void AdjustHeap(MaxHeap H){
//假设所有的元素(H->Size个)已存入H->Data[]中,无哨兵
long i;
for(i=H->Size/2-1;i>=0;i--)//(N-1-1)/2为最后一个有孩子的节点
{
PercDown(H,i);
}
}
ElementType DeleteMax(MaxHeap H)
{
ElementType X=H->Data[--H->Size];
ElementType MaxData=H->Data[0];//需返回的根节点存放的值
int intend=0,Child;//MinChild为最小儿子的下标
for(;intend*2+1<=H->Size-1;intend=Child){
Child=2*intend+1;
if( Child+1<=H->Size-1 && H->Data[Child+1] > H->Data[Child]) Child++;//如果有右儿子且右儿子的值小
if(X>=H->Data[Child]) break;
H->Data[intend]=H->Data[Child];
}
H->Data[intend]=X;
return MaxData;
}
void HeapSort(ElementType a[],long N){
Heap H=(Heap)malloc(sizeof(struct HNode));
H->Data=(ElementType *)malloc((CAPACITY)*sizeof(ElementType));
H->Size=0;
H->Capacity=CAPACITY;
long i;
for(i=0;i<N;i++)
H->Data[i]=a[i];
H->Size=N;
AdjustHeap(H);
for(i=N-1;i>=0;i--){
ElementType X=DeleteMax(H);
a[i]=X;
}
}
ElementType DeleteMax(MaxHeap H)
{
ElementType X=H->Data[--H->Size];
ElementType MaxData=H->Data[0];//需返回的根节点存放的值
H->Data[0]=X;/************DeleteMax可以改为这种方式*************/
PercDown(H,0);
return MaxData;
}
2)直接在原数组内每次将堆头最大元素删除放到末尾。
typedef int ElementType;
void PercDown(int a[],long i,long N){
ElementType X=a[i];
long child;
for(;2*i+1<=N-1;i=child){
child=2*i+1;
if(child+1<=N-1 && a[child+1]>a[child])
child++;
if(X>=a[child]) break;
a[i]=a[child];
}
a[i]=X;
}
void AdjustHeap(int a[],long N){
//假设所有的元素(H->Size个)已存入H->Data[]中,无哨兵
long i;
for(i=N/2-1;i>=0;i--)//(N-1-1)/2为最后一个有孩子的节点
{
PercDown(a,i,N);
}
}
void HeapSort(ElementType a[],long N){
long i;
AdjustHeap(a,N);
// putchar('\n');
// for(i=0;i<H->Size;i++)
// printf("%d ",H->Data[i]);
// putchar('\n');
for(i=N-1;i>0;i--){
int temp=a[i];
a[i]=a[0];
a[0]=temp;
PercDown(a,0,i);
}
}
5.归并排序
1)递归算法
//将两个排序好的序列合并导入到temp中,再导回a中
void MSort(ElementType a[],ElementType temp[],long Left,long Right,long End){
long i,j,k;
k=Left;i=Left;j=Right;
while(i<Right && j<=End){
if(a[i]<=a[j]){
temp[k]=a[i];
i++;
}else {
temp[k]=a[j];
j++;
}
k++;
}
while(i<Right){
temp[k]=a[i];
i++;k++;
}
while(j<=End){
temp[k]=a[j];
j++;k++;
}
for(i=Left;i<=End;i++)
a[i]=temp[i];
}
void Merge( ElementType A[], ElementType TmpA[], long L, long RightEnd )
{ /* 核心递归排序函数 */
long Center;
if ( L < RightEnd ) {
Center = (L+RightEnd) / 2;
Merge( A, TmpA, L, Center ); /* 递归解决左边 */
Merge( A, TmpA, Center+1, RightEnd ); /* 递归解决右边 */
MSort( A, TmpA, L, Center+1, RightEnd ); /* 合并两段有序序列 */
}
}
void MergeSort(ElementType a[],long N){
long i;
int temp[N];
Merge(a,temp,0,N-1);
}
2)非递归的归并排序
//将两个排序好的序列合并导入到temp中,再导回a中
void MSort(ElementType a[],ElementType temp[],long Left,long Right,long End){
long i,j,k;
k=Left;i=Left;j=Right;
while(i<Right && j<=End){
if(a[i]<=a[j]){
temp[k]=a[i];
i++;
}else {
temp[k]=a[j];
j++;
}
k++;
}
while(i<Right){
temp[k]=a[i];
i++;k++;
}
while(j<=End){
temp[k]=a[j];
j++;k++;
}
for(i=Left;i<=End;i++)
a[i]=temp[i];
}
void MergeSort(ElementType a[],long N){
int temp[N];
long Length=1,i;
for(;Length<=N;Length*=2){
i=0;
for(;i<N;i+=2*Length){
if(i<=N-2*Length)
MSort(a,temp,i,i+Length,i+2*Length-1);
else if(i+Length<N)
MSort(a,temp,i,i+Length,N-1);
}
}
6.快速排序(这个是在考前复习阶段按照书上写的,比较慢)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#define CAPACITY 100000
typedef int ElementType;
int Partition(int L[],int low,int high){
int PivotKey=L[low];
while(low<high){
while(low<high && PivotKey<=L[high])
high--;
L[low]=L[high];
while(low<high && L[low]<=PivotKey)
low++;
L[high]=L[low];
}
L[high]=PivotKey;//最后high==low,填入枢轴
return high;
}
void QSort(int L[],int low,int high){
int PivotLoc;
if(low<high){
PivotLoc=Partition(L,low,high);
QSort(L,low,PivotLoc-1);
QSort(L,PivotLoc+1,high);
}
}
void QuickSort(int L[],int N){
QSort(L,0,N-1);
}
//int comp(const void* a,const void* b){
// return *(int*)a-*(int*)b;
//}
int main()
{
int N,i;
scanf("%d",&N);
int a[N];
for(i=0;i<N;i++) scanf("%d",a+i);
QuickSort(a,N);
//qsort(a,N,sizeof(int),comp);
bool IsFirst=true;
for(i=0;i<N;i++){
if(IsFirst==true){
printf("%d",a[i]);
IsFirst=false;
}else
printf(" %d",a[i]);
}
return 0;
}