#include<iostream>
#include<stdlib.h>
#include<time.h>
#define n 10000
using namespace std;

const int maxn=1e6+10;
int a[maxn],b[maxn];

void display(){
	for(int i=0;i<n;i++){
		printf("%4d",a[i]);
	}
	puts("");
}
void insertsort(){
	for(int i=1;i<n;i++){
		if(a[i]<a[i-1]){
			int temp=a[i];
			int j=i-1;
			do{
				a[j+1]=a[j];
				j--;
			}while(j>=0&&a[j]>temp);
			a[j+1]=temp;
		}
	}
}
void midinsertsort(){
	for(int i=1;i<n;i++){
		if(a[i]<a[i-1]){
			int temp=a[i];
			int low=0,high=i-1;
			while(low<=high){
				int mid=(low+high)>>1;
				if(a[mid]>temp){
					high=mid-1;
				}else{
					low=mid+1;
				}
			}
			for(int k=i-1;i>=high+1;i--){
				a[k+1]=a[k];
			}
			a[high+1]=temp;
		}
	}
}
void shellsort(){
	int N=n/2;
	while(N>0){
		for(int i=N;i<n;i++){
			if(a[i]<a[i-N]){
				int temp=a[i];
				int j=i-N;
				do{
					a[j+N]=a[j];
					j-=N;
				} while(j>=0&&a[j]>temp);
				a[j+N]=temp;
			}
		}
		N=N/2;
	}
}
void shift_up(int id){
	if(id==1)return ;
	if(b[id]<b[id/2]){
		swap(b[id],b[id/2]);
		shift_up(id/2); 
	}
}
void shift_down(int id,int N){
	if(id*2>N)return ;
	int k=id;
	if(b[id*2]<b[k])k=id*2;
	if(id*2+1<=N&&b[id*2+1]<b[k])k=id*2+1;
	if(k==id)return ;
	swap(b[k],b[id]);
	shift_down(k,N);
}
void heapsort(){
	for(int i=1;i<=n;i++){
		b[i]=a[i-1];
	}
	for(int i=n;i>=1;i--){
		shift_up(i);
	}
	for(int i=n;i>=1;i--){
		b[1]=b[i];
		shift_down(1,i-1);
	}
}
void bubblesort(){
	for(int i=0;i<n-1;i++){
		for(int j=i;j<n;j++){
			if(a[j]>a[j+1]){
				swap(a[j],a[j+1]);
			}
		}
	}
}
void merge(int *A,int x,int y,int *T){
	if(y-x>1){
		int m=x+(y-x)/2;
		int p=x,q=m,i=x;
		merge(A,x,m,T);
		merge(A,m,y,T);
		while(p<m||q<y){
			if(q>=y||(p<m&&A[p]<=A[q]))T[i++]=A[p++];
			else T[i++]=A[q++];
			for(i=x;i<y;i++)A[i]=T[i];
		}
	}
}
void merge_sort(){
	int t[10000];
	merge(a,0,n-1,t);
}
void QSort__(int *a,int low,int high)
{
 	int i, j;
 	if(low>=high) return;
 	i=low; j=high;
 	int temp=a[i];
 	while(i<j){
 		while(j>i&&a[j]>temp)j--;
 		a[i]=a[j];
 		while(i<j&&a[i]<=temp)i++;
 		a[j]=a[i];
	}
	a[i]=temp;
 	QSort__(a,low,i-1);
 	QSort__(a,i+1,high);
}
void quick_sort(){
	QSort__(a,0,n-1);
}
double Time;
void run(void(*f)()){
	clock_t start,stop;
	start=clock();
	(*f)();
	stop=clock();
	Time =((double)(stop - start))/CLK_TCK;
}
void setNum(){
	for(int i=0;i<n;i++){
		a[i]=rand()%101;
	}
}
int main(){
	printf("升序排序\n");
	srand(time(0));
	setNum();
	run(bubblesort);
	printf("\n冒泡排序绝对执行时间:%lf\n",Time);
	setNum();
	run(heapsort);
	printf("\n堆排序绝对执行时间:%lf\n",Time); 
	setNum();
	run(shellsort);
	printf("\n希尔排序绝对执行时间:%lf\n",Time);
	setNum();
	run(midinsertsort);
	printf("\n二分插入排序绝对执行时间:%lf\n",Time);
	setNum();
	run(insertsort);
	printf("\n直接插入排序绝对执行时间:%lf\n",Time);
	setNum();
	run(merge_sort);
	printf("\n归并排序绝对执行时间:%lf\n",Time);
	setNum();
	run(quick_sort);
	printf("\n快速排序绝对执行时间:%lf\n",Time);
	printf("\n");
}