04、算法系类,快速排序代码实现 + 讲解

    如果你已经学会C,C++(或看过《C++Primer》)的基本语法,想要再精进一层的话,那就是该接触数据结构与算法的时候了,这个系列博文的主题亦如此,所提供的代码都是在学习这些的过程中,自己写的代码,且亲测有效。

    无数前辈说过,程序 = 数据结构 + 算法,数据结构就是内存对数据的存储方式,算法就是对数据的加工处理。那么对于超大量的数据,为了管理他们,为了以后好取出想要的值,对他们的加工处理基本上都是按照各种排序方式,排来排去。

  《Effictive C++》赞美之音传于四海,这本书的中文翻译者侯捷,他老人家更是桃李满天下。他第一次听人说了电脑就是对存进来的数据排一下序,很难相信,他认为因为电脑是一种顶级高科技的存在,是用来发射火箭的,怎么就只排排数据。所以很容易忽略排序的重要性,因为我们平时都是处理的小量数据,想取哪一个数据手动,输出一下就行了。

    举个业务上的例子,现在各个银行都在建设5G银行,系统会保存客户的人脸图片,当客户下次去银行的时候,门口会有声音欢迎王先生光临~。因为门口会有摄像头做人脸拍照,然后与数据库的照片比对排序。这种比对是一个个比吗,如果客户在上亿的量,一个个比太慢了,系统的实现是按照图片上的特性值,把之前在数据库中存的上亿照片按照一定的方式排序,这样就不需要一个个比对,可以用二分查找这类方法快速找到。

    排序算法,分两部分,业务 + 代码,业务即是算法怎么实现这个功能的,文字上描述一下,代码是具体是实现。无论上个小系列数据结构还是接下来的算法,我都将采用这种方式讲解。理解业务更易看懂代码,然有些业务说起来很抽象,照猫画虎的不好文字描述,直接看代码范围理解快一点,所以两者可以结合着来理解。

    刚开始学前几个排序时,这些排序是最简单的也是最难的,最简单是因为学了好久之后再回来看,最难是因为刚刚接触的前几个排序,一看晕了,再看排序算法这么多,放弃了。其实不然,只要学会几个,后面就会很轻松,还有助于你以更高的视野看前面学过的算法。

    快速排序相对于前三节讲的冒泡排序,选择排序,直接插入,又提供了一种新的排序思路:

    若按左小右大的方式排序,它首先选择最左边为基准值,然后定义int i,j 两个下标变量,i指向左数第二个数,j指向最后一个数。总体上来说排序的业务就是,让 i 左边的值都比基准值小,j 右边的值都比基准值大,然后 i 向右移,带动 j 向左移。具体业务:全部由i指向的数来跟基准数比较,若小于基准值,i++ 。若大于则i位置的数与j位置的数互换,换后 j-- ,i并不加一,因为此时 i 位置的数依然有可能大于基准值,因此再比较一次。此时依然有两种情况跟上所述一样(注意这时 j 已将向左移动一位了)。接下来若是 i ++ 的情况,i++位置上的数跟基准值比较,比较的两种情况跟上述一样。第一次接触可能有些不好理解,因为它的业务有迭代的思路,建议拿笔在纸上按刚才的表述模拟一下便更易明白。 i 跟 j 一直靠近,直到相等。此时再把这个位置上的值跟基准值比较,判断大小。然后把左边小于基准值的与右边大于基准值的看成两个分区,基准值分别取两个分区最左边的值,在两个分区里分别执行上述的业务。后边变成四个分区,继续迭代下去。最后你会神奇的发现整个数组有序,用一个小数组,在纸上模拟一遍体会更易体会。

   

    郭襄:我走过山时,山不说话,我路过海时,海不说话。
     

     很多时候,这个世界是自己的跟他人无关,生活需要自己去探索。

上代码,亲测有效!

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_SIZE 10
//交换函数
void Swap(int* a, int* b)
{
	int temp;
	temp = *a;//*a是一个变量
	*a = *b;
	*b = temp;
	return;
}
//打印数组
void Print(int myArray[])
{
	for (int i = 0; i < 10; i++)
	{
		printf("myArray数组:%d ", myArray[i]);
	}
	printf("\n");
}

//快速排序算法
void QuickSort(int myArray[10], int begin, int end)
{
	//判断是否继续迭代
	if (begin < end)
	{
		int i = begin + 1;
		int j = end;
		while (i < j)//i == j 时跳出循环
		{   
			//选择myArray[begin]作为基准
			if (myArray[i] > myArray[begin])
			{
				Swap(&myArray[i], &myArray[j]);
				j--;
			}
			else
			{
				i++;
			}
		}
		//跳出循环时,myArray[i]并没有与基准myArray[begin]比较
		if (myArray[i] >= myArray[begin])
		{
			//将基准值与i的前一位交换
			i--;
			Swap(&myArray[i], &myArray[begin]);
		}
		else
		{
			//将基准值与i交换
			Swap(&myArray[i], &myArray[begin]);
		}
		//此时分为两个范围,跳出循环时,i等于j
		//myArray[begin]~myArray[i]与myArray[j]~myArray[end]
		//开始迭代
		QuickSort(myArray, begin, i);
		QuickSort(myArray, j, end);
	}
}
int main(void)
{
	int myArray[MAX_SIZE] = { 2, 1, 4, 3, 6, 5, 8, 7, 0, 9 };
	//打印数组
	Print(myArray);
	//调用快速排序算法
	QuickSort(myArray, 0, 9);
	//打印数组
	Print(myArray);
	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

、、、、南山小雨、、、、

分享对你有帮助,打赏一下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值