手撕代码 --排序算法

本文详细介绍了三种经典的排序算法:快速排序、归并排序和选择排序。快速排序通过选取基准元素进行分区,然后递归排序子区间的策略实现高效排序;归并排序则采用分治法,将序列两两合并,最终达到排序目的。非递归版本的归并排序展示了如何逐步合并序列;选择排序每次找到最小元素与目标位置交换,确保每趟结束后序列部分有序。这些排序算法在不同的场景下各有优势,对于理解算法思想和优化数据处理具有重要意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值