排序算法(Sorting Algorithm)

排序算法

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。在各个领域中考虑到数据的各种限制和规范,要得到一个符合实际的优秀算法,得经过大量的推理和分析。


1. 冒泡排序

排序步骤
  1. 从数组的第一个数arr[0]开始遍历,(i从0到n-1)如果第i个数比第i+1个数大arr[i]>arr[i+1],则交换
  2. 重复上述步骤直至数组有序

分析

冒泡排序可以说是最简单的排序方法之一,最坏的情况需要排n-1趟。我们可以设置一个flag来监测排序过程中是否产生的数的交换,如果没有,说明数组已经有序,则可以不用进行下一趟排序。


C语言实现
void bubble_sort(int arr[],int n)
{
	int flag,tmp;
	for(int i = 0; i < n-1; i++)
	{
		flag = 0;
		for(int j = 0;j<n-1;j++)
			if(arr[j]>arr[j+1])
			{
				tmp      =  arr[j];
				arr[j]   =  arr[j+1];
				arr[j+1] =  tmp;
				flag     =  1;
			}
		if(!flag)
			return;
	}
}

2.快速排序算法

排序步骤
  1. 在当前区域(记为area)(area初始为整个无序数组)选定一个数作为基准数(记为key)
  2. 遍历数组,把所有大于key的数(记为high)放在右边,把所有小于key的数(记为low)放在左边(并不关心这些数是否有序)
  3. key放在lowhigh的中间
  4. 现在area又被分为三个区域,lowkeyhigh,分别选择lowhigh作为新的area,分别重复上述流程

原理分析

每次我们在当前area中把所有数以key为中间数摆放好,实质上就是在整个数组中确定好了key这个数最终的位置,左边的数都比key小,右边的数都比key大。不断重复这个过程那么最终所有数都必将摆在最终的位置


手动排序示例

下面是一个无序数组:

8 ,5, 2, 3,-1 , 7

当前area为[0] ~ [5] (数组编号)我们选择中间的一个数2作为本轮的key
从两端开始找:

7key 大,没毛病
-1key 小,扔到最左边,现在数组:

-1,5, 2, 3, 87

移动过的数比过大小没移动的数都是已处理的数(我用粗体标记了),待在了自己该待在的区域,因此我们不需要对这些数再进行操作,也不应该用其他的数来填充他们的位置,因为我们不关心他们之间是否有序,只关心他们和key的位置关系是否正确

然后我们从左边开始找,(如果继续从右边找会重复工作,不信你可以动手试一下)
-1是刚刚丢过来的,不用管
5key大,移动到未处理的最右边:

-1,3,2,587

我们并没有检查交换过来的数和key的关系,因此交换过来的数是未处理的数
继续,2等于key,移到左边:(等号的情况必须得移动,不然key的位置就被固定了!但比key小的数在key左边不一定放的下)

-12,3,587

最后3的位置是在2右边的,不需要动,第一趟完成,现在[0]是low,[2]~[5]high
因为low只有一个数,不需要继续处理
现在high是新的area:

3,5,8 ,7

为了展示key的选取不影响排序结果(虽然影响排序效率),我们选择第一个数3作为key
那么跑完整个流程,所有的数都大于等于3,这次就没有low区域了
选择新的high作为area

5, 8, 7

这次又随机选,选最后一个数7(读者可以自行尝试选取其他的key进行排序)
7不动,8key

5, 7, 8

到这显而易见已经完成了

C语言实现
void quick_sort(int arr[],int l,int r)
{
    if(l>=r) return;
    int i=l,j=r,key=arr[l];
    while(i<j)
    {
        while(i<j && arr[j]>=key) j--;
        if(i<j) arr[i++]=arr[j];
        while(i<j && arr[i]<=key) i++;
        if(i<j) arr[j]=arr[i];
    }
    arr[i]=key;
    quick_sort(arr,l,i-1);
    quick_sort(arr,i+1,r);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值