手撕代码 --排序算法

1.快排

快排的思想:随机选取一个数字,数字的右边都比这个数字小,数字的左边都比这个数大。
快排

int partition(int A[],int left,int right)
{	
	int temp=A[left];
	while(left<right)
	{
		while(left<right&&A[right]>temp)right--;
		A[left]=A[right];
		while(left<right&&A[left]<=temp)left++;
		A[right]=A[left];
	}
	A[left]=temp;
	return left;	//返回相遇的下标
}

void quicksort(int A[],int left,int right)
{
	if(left<right)
	{
		int pos=partition(A,left,right);
		quicksort(A,left,pos-1);	//对左子区间递归进行快速排序
		quicksort(A,pos+1,right);	//对右子区间递归进行快速排序
	}
}


2.归并排序

二路归并排序
1.将序列两两分组,就可以得到n/2个组,组内单独排序,然后再将这些组两两合并。
递归方案

const int maxn=100;
void  merger(int A[],int l1,int r1,int l2,int r2)
{
	int i=l1,j=l2;
	int temp[maxn];
	int index=0;
	while(i<=r1&&j<=r2)
	{
		if(A[i]<A[j])
		{
			temp[index++]=A[i++];
		}else
		{
			temp[index++]=A[j++];
		}
	}
	while(i<=r1)temp[index++]=A[i++];
	while(i<=r2)temp[index++]=A[j++];
	for(i=0;i<index;i++)
	{
		A[l1+1]=temp[i];
	}
}

void mergersort(int A[],int left,int right)
{
	if(left>right)return;
	int mid=left+(right-left)/2;
	mergersort(A,left,mid);
	mergersort(A,mid+1,right);
	merge(A,left,mid,mid+1,right);
}

非递归版本

void mergeSort(int A[])
{
	//step为组内元素,step/2为左区间元素个数
	for(int step=2;step/2<=n;step*=2)
	{
	//每step个元素为一组,组内前 step/2 个元素 和 后step/2个元素进行合并
		for(int i=1;i<=n;i+=step)
		{
			int mid=i+step/2-1;
			if(mid+1<=n)
			{
				merge(A,i,mid,mid+1,min(i+step-1,n));
			}
		}	
	}
}

如果只要求给出归并排序每一趟结束时的序列

void mergeSort(int A[])
{
	//step为组内元素,step/2为左区间元素个数
	for(int step=2;step/2<=n;step*=2)
	{
	//每step个元素为一组,组内前 step/2 个元素 和 后step/2个元素进行合并
		for(int i=1;i<=n;i+=step)
		{
			sort(A+i,A+min(i+step,n+1));
		}	
	}
}

3.选择排序

每一趟从待排序的部分[i,n]中选择最小的元素,然后与A[i]进行交换

void selectsort()
{
	for(int i=1;i<=n;i++)
	{
		int k=i;
		for(int j=i;j<=n;j++)
		{
			if(A[j]<A[k])
			{	
				k=j;
			}
		}
		int temp=A[i];
		A[i]=A[k];
		A[k]=temp;
	}
}

4.插入排序

A[0,i-1]有序,将i插入

int A[maxn],n;
void insertSort()
{
	for(int i=2;i<=n;i++)
	{
		int temp=A[i],j=i;
		while(j>1&&temp<A[j-1])
		{
			A[j]=A[j-1];
			j--;
		}
		A[j]=temp;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值