leetcode刷题——算法(2):排序算法(上)

排序算法(2.11)

O(N2)

简单排序

从序列中找到最小数,与第一个数交换;再从剩下的数中,找到最大数,与第二个数交换

比较次数为N(N-1)/2

O(N2)

冒泡排序

从后往前,相邻两个数进行比较,如前一个数大于后一个数,交换,如此一轮最小位于第一位;重复,交换至第二位。。

比较次数为N(N-1)/2,相较上者交换次数减小

O(N2)

插入排序

一个个插入

O(N2)

希尔排序

升级版冒泡排序,比较间隔由大至小减小,N/2,N/4,...,1

降低交换次数

O(N2)

O(NlogN)

快速排序

选择一个基准,双指针,一个从头,一个从尾,头小于等于基准,尾大于基准,不满足时交换;然后分别递归对前后段递归使用,此种方法在序列大小大于某个阈值时使用。

基准选择标准可以是头、尾、中间值三者的中位数。

最好时间复杂度为O(NlogN),每次正好平分;最差情况为O(N2),为一个斜二叉树,每次分为一个跟剩下的。

平均为O(NlogN)

堆排序※

先生成堆,将第一个元素与最后一个元素交换,剩下的n-1个元素再生成堆。

向下调整成为堆。(从小到大排序应该形成最大堆)

平均为O(NlogN)

归并排序※

分而治之,关键在于合并函数。

一开始就声明一个临时内存,节省空间。

O(NlogN)

 

void swap(int& a,int& b){
	int tmp=a;
	a=b;
	b=tmp;
}

/***简单排序***/
void SimpleSort(int a[],int n){
	for(int i=0;i<n;i++){
		int mini=i;
		for(int j=i+1;j<n;j++)
		   if(a[j]<a[mini])  mini=j;
		if(mini!=i) swap(a[mini],a[i]);
	}
} 

/***插入排序***/
void InsertSort(int a[],int n){
	for(int i=0;i<n;i++){
		int tmp=a[i];
		int j=i-1;
		for(;j>=0;j--){
			if(a[j]>tmp) a[j+1]=a[j];
			else break;
		}
		a[j+1]=tmp;
	}
}

/***冒泡排序***/
void PopSort(int a[],int n){
	for(int i=0;i<n;i++){
		for(int j=n-1;j>i;j--)
		   if(a[j]<a[j-1]) swap(a[j],a[j-1]);
	}
} 

/***希尔排序***/
void XierSort(int a[],int n){
	for(int k=n/2;k>0;k/=2){
		for(int i=k;i<n;i++)
		   for(int j=i-k;j>=0;j-=k)
		      if(a[j+k]<a[j]) swap(a[j+k],a[j]); 
	}
}


/***快速排序***/
int median(int a,int b,int c){
	int res=(a>b)?a:b;
	return (res<c)?res:c;
}
void partion(int a[],int left,int right){
	if(right-left>2){
		int mid=(left+right)/2;
		int thresh=median(a[left],a[right],a[mid]);
		int i=left,j=right;
		while(i<j){
			while(a[i]<thresh) i++;
			while(a[j]>thresh) j--;
			if(i<j) swap(a[i],a[j]);
		}
		partion(a,left,i-1);
		partion(a,i+1,right);
	}else{
		for(int i=left;i<=right;i++){
			int tmp=a[i];
			int j=i-1;
			for(;j>=left;j--) 
			   if(a[j]>tmp) a[j+1]=a[j];
			   else break;
			a[j+1]=tmp;
		}
	}	
}
void QuickSort(int a[],int n){
	partion(a,0,n-1);
}

/***堆排序***/
void adjustDown(int a[],int i,int n){
	int child,tmp=a[i];
	for(;2*i+1<n;i=child){
		child=2*i+1;
		if(child!=n-1&&a[child+1]>a[child]) child++;
		if(a[child]>tmp) a[i]=a[child];
		else break;
	}
	a[i]=tmp;
} 
void HeapSort(int a[],int n){
	for(int i=n/2;i>=0;i--) 
	    adjustDown(a,i,n);
	for(int i=n-1;i>0;i--){
		swap(a[0],a[i]);
		adjustDown(a,0,i);
	}
} 

/***归并排序***/
void Merge(int a[],int tmpa[],int left,int mid,int right){
	int numElem=right-left+1;
	int tp=left,leftend=mid-1;
	while(left<=leftend&&mid<=right){
		if(a[left]<a[mid]) tmpa[tp++]=a[left++];
		else tmpa[tp++]=a[mid++];
	}
	while(left<=leftend) tmpa[tp++]=a[left++];
	while(mid<=right) tmpa[tp++]=a[mid++];
	for(int i=0;i<numElem;i++,right--)
	   a[right]=tmpa[right];
} 
void Msort(int a[],int tmpa[],int left,int right){
	if(right>left){
		int mid=(left+right)/2;
		Msort(a,tmpa,left,mid);
		Msort(a,tmpa,mid+1,right);
		Merge(a,tmpa,left,mid+1,right);
	}
}
void MergeSort(int a[],int n){
	int *tmpa=(int*)malloc(n*sizeof(int));
	Msort(a,tmpa,0,n-1);
	free(tmpa);
}

int main(){
	int a[10]={3,5,2,4,6,8,7,1,0,9};
	int b[10]={3,5,2,4,6,8,7,1,0,9};
	
	SimpleSort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
		a[i]=b[i];
	}
	printf("\n");
	
	InsertSort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
		a[i]=b[i];
	}
	printf("\n");
		
	PopSort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
		a[i]=b[i];
	}
	printf("\n");
	
	XierSort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
		a[i]=b[i];
	}
	printf("\n");
	
	QuickSort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
		a[i]=b[i];
	}
	printf("\n");
	
	HeapSort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
		a[i]=b[i];
	}
	printf("\n");
	
	MergeSort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
		a[i]=b[i];
	}
	printf("\n");
	
	return 0;	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值