c++的各种排序

o(n2)的排序

以下三种排序比较好的是插入排序

插入排序

思想:设前i个元素已经有序,然后把第i+1个元素插到合适的位置上

void ins_sort()
{
	for(int i=2;i<=n;i++)
	{
		a[0]=a[i];
		//先记住这个数的大小,因为他马上要被替换,且a[0]充当比较的终点.
		for(int j=i-1;j>=a[0];j--)//如果比要插入得数大,就要整体往后移动
			a[j+1]=a[j];
		a[j+1]=a[0];
	}
}

选择排序

思想:处理第i个元素时,找到他后面数的最小值.如果这个最小值比他小,就相互交换

void swap_sort(int start,int end)
{
	for(int i=start;i<end;i++)
		for(int j=i+1;j<end;j++)
			if(a[i]>a[j])
				swap(a[i],b[i]);
}

冒泡排序

void bubble_sort(int start,int end)]
{
	for(int i=start;i<end;i++)
		for(int j=end;j>i;j--)//从start到i,在"冒泡"过程中,元素已经排好序
			if(a[j-1]>a[j])
				swap(a[j],a[j-1]);
}

o(nlogn)的排序

快速排序

快速排序俗称"快排",是基于比较排序中比较快的一种算法.可以去网上搜索快苏排序的视频来加深理解,这是典型的分治的思想.

void quicksort(int start,int end)
{
	int low=start,heigh=end;
	int temp,check=a[(start+end)/2];
	//check有时候选择一个从start到end的随机数
	//划分:把check小的数据放到他的左边,吧check大的数放到他的右边.
	while(low<=high)
	{
		while(a[low]<check&&low<=high) low++;
		while(a[high]>check&&low<=high) high--;
		if(low<=high)
		{
			swap(a[low],a[high]);
			low++;high--;//这两句很关键
		}
	}
	//递归:对已经划分好的两部分分别进行快速排序
	if(high>start) quicksort(start,end);
	if(low<end) quicksort(low,end);
}

归并排序

void merge(int low,int mid,int high)
{
	int n=high-low+1;
	int i=low,end1=mid;
	int j=mid+1,end2=high;
	int k=0;
	while(i<=end1&&j<=end2)
	{	
		//将array[i]和array[j]中最小的这个赋给temp[k]
		if(array[i]<=array[j]) temp[k]=array[i++];
		else 				   temp[k]=array[j++];
		k++;
	}
	while(i<=end1) temp[k++]=array[i++];
	while(j<=end2) temp[k++]=array[j++];
	for(int x=0;x<k;x++)
		array[low+x]=temp[x];
}
void merge_sort(int low,int high)//分开解决
{
	if(low<high)
	{
			int mid=low+(hight-low)>>1;//二分
			//递归分治
			merge_sort(low,mid);
			merge_sort(mid+1,high);
			merge(low,mid,high);//二路归并
	}
}

堆排序

思想:用对的特性来完成排序
实现过程:
1.将数组转化成一个堆(使用buildheap完成).
2将堆顶的最大元素取出(removemax),并把它放到数组最后(准确的说,位置是对中的元素减1).
3.剩余的重新排列.
4.重复2,直到堆为空.
堆排序相比其他o(nlogn)的排序算法要慢很多,适合寻找第k大(小)的元素

o(n)的排序

桶排序

思想:设计n个桶,根据元素本身进行分配.因为m个桶是按顺序排列的,所以分配元素之后元素也会按照顺序排列,(n<=1e6)

int cnt[M+10];
memset(cnt,0,sizeof(cnt));//在cstring库中,将数组整体赋值为0.
for(int i=0;i<N;i++)
	cnt[a[i]]++;
//从cnt[0]开始枚举就行了.例如
for(int i=0;i<M;i++)
	while((cnt[i]--)>0)
		cout<<i<<' ';	

STL库中的排序

原型:
void sort<_Ranlt>(const_Ranlt_first,const_Ranlt_last);
这个排序是o(nlogn)的,会经常用到,相比其他o(nlogn)的排序代码简洁了不少,因为里面自带有好多种排序.

void stl_sort(int end)
{
	sort(a+1,a+end+1);
}

总结

算法比较:
1.稳定性
插入排序,冒泡排序,归并排序其他线性的排序是稳定的.
选择排序,快速排序等是不稳定的.
2.时间复杂度
前面标题上说了
3.辅助空间
线性时间排序,归并排序的辅助空间为o(n).
其他的排序为o(1);
4.其他方面
插入,冒泡排序速度较慢,但待排序的队列基本有序时,这种排序能达到较快的速度.在这种情况下,快速排序反而慢了.
当n较小时,对稳定性不作要求时宜用选择排序,对稳定性有要求时宜用插入或冒泡排序.若待排序的记录的关键字在一个明显有范围内时,若空间允许用桶排序
当n较大时,关键字元素比较随机,对稳定性没有要求时宜用快速排序.
当n较大时,关键字元素可能出现本身是有序的,对稳定性有要求时,空间允许的情况下,宜用归并排序.
当n较大时,关键字元素可能出现本身是有序的,对稳定性没有要求时宜用堆排序

end

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值