写给自家娃看的算法书----快速排序,C语言实现

本文介绍了快速排序的基本思想和C语言实现过程。通过对比冒泡排序,阐述了快速排序的优势,详细讲解了如何选取基准元素以及如何通过虫虫和东东找到基准元素的正确位置。文中给出了递归实现的快速排序代码,并分析了其平均时间复杂度和空间复杂度。
摘要由CSDN通过智能技术生成

排序方法可以分为比较算法和非比较算法两大类。其中比较算法就有7种:
冒泡排序 (初级) ----> 快速排序 (高级)
选择排序 (初级) ----> 堆排序 (高级)
插入排序 (初级) ----> 希尔排序 (高级)
归并排序 (高级)
这里只介绍一种非比较排序:桶排序。
8种排序算法中快速排序、堆排序和归并排序这三种算法位列“十大算法”,可见排序算法的重要性。

如果有一个数组arr = {4, 1, 5, 9, 7, 2, 8, 6, 4, 3}。希望把它按照从小到大排序,我们该怎么做呢?当然是排序喽。我们在学C语言的时候已经学过最简单,但是效率也是最低的冒泡排序了。这里就不再赘述。我们就稍稍讨论一下冒泡排序的问题:
冒泡排序就是一个数据跟相邻的数据进行比较,如果次序不符合要求,那就交换一下,然后继续往下交换,直到一轮循环结束。这样一轮下来,只能保证一个数据到达最底部。接下去进行第二轮、第三轮。。。一共需要n轮,整个排序结束。所以时间复杂度为O(N2)。
冒泡排序的问题是只有相邻的两个元素之间才能进行比较,这样就比较慢了。如果让整个数组中的任意两个元素都能相互比较大小,是不是就能加速呢?我们来看看快速排序吧。

1 快速排序

快速排序的思想是让一个元素作为基准,然后虫虫 (i) 和东东 (j) 帮忙找到基准的家,接着交换基准元素与占据他家的元素。这时基准元素就找到了家。最后把基准元素的左边部分用同样的方法继续排序,右边部分也用同样排序,直到整个数组中的元素变得有序。这个方法比较厉害的是把数组分成三部分:左边部分、中间正确摆放的一个元素、右边部分。
我们可以让任意一个元素都放到它正确的位置,简单起见,我们就取最左边的元素作为基准。问题来了,我们怎么知道这个元素的家在哪呢?这就是快速排序最奥妙的地方了。如果我们能让比基准小的元素都放在左边,比基准大的元素都放在右边,那么中间的位置就是这个基准该在的位置。

在这里插入图片描述
具体来说,如果虫虫在数组最左边,东东在数组最右边 (初始状态)。东东是弟弟,所以虫虫让弟弟先开始往左走,如果遇到 >= 基准的元素就继续走,遇到 < 基准的元素就停下来;接着是虫虫开始往右走,如果遇到 <= 基准的元素就继续走,遇到 > 基准的元素就停下来。如果两个小朋友都停下来的时候他们还没有相遇,那就交换这两个小朋友所在的元素。接着继续东东往左走,虫虫往右走。一直到两兄弟相遇。这个相遇的地方就是基准的家啦。把占据了基准家的元素跟最左边的元素交换一下位置,基准就到家了。
上面的过程就把一个数组分成了三段。左边一段和右边一段分别用同样的方法继续就可以了。中间那个元素因为已经找到正确的位置了,它就不需要动了。下面我们就来看看虫虫和东东帮基准找家的代码:

int num = arr[low]; //取最左边的元素作为基准 
int i = low; //虫虫在最左边 
int j = high; //东东在最右边 

while(i < j) //虫虫和东东没有相遇的时候继续走 
{
   
	//虫虫是哥哥,要让着弟弟,所以每次都是东东先走。 
	while(i < j && num <= arr[j]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值