快速排序算法小记

前言

快速排序是一种很实用的排序算法。今天在网上看到有网友谈论快速排序是什么。想想自己记得也不是很清楚了,索性就写一篇小记,复习一下。

1 简介

快速排序是对冒泡排序的一种改进。

它的核心思想是:通过一趟排序将要排序的数列分成两个独立的新数列,其中一个新数列的每个元素都比另一个新数列的任何一个元素要小。之后,对这两个数列再次进行快速排序。

2 算法性质

内部排序

快速排序是一种内部排序算法。即参与快速排序的对象都是存储在内存中的。(了解一下 外部排序 )

不稳定性

在排序算法中,假设待排序数列中有两个元素a、b,其中a.key == b.key,若排序算法不能保证a和b在数列中的相对位置,则称排序算法是不稳定的。

例如:有数列 'yabx',其中 y.key > a.key == b.key > x.key。经排序,得到数列 'xbay'。此时,数列为升序,是有序的。但a和b的相对位置想比较于排序前,发生了颠倒,我们称这种排序就是不稳定的,它可能改变元素的相对排列顺序。

原地排序

原地排序意味着排序算法随问题规模增大,对额外内存空间的需求是常数级的(S(1))。所以,在内存受限的系统中,快速排序也能很好地工作。

3 算法描述

为了便于理解。这里给出一个待排序的数列: 6, 2, 3, 7, 1, 5, 4, 8, 9

第一趟排序
step1,选取待排序数列(以下称 '数列')中索引为 '0' 的元素(记为 pivot)作为本趟排序的主轴,记 pivot 当前索引位置为 pre_pos 。 (pivot.key == 6pre_pos == 0,此时数列为原始数列: 6, 2, 3, 7, 1, 5, 8, 4, 9

step2,从数列末尾对数列遍历(为便于理解,以下称 '从右到左遍历'),找到第一个比 pivot.key 小的元素(记为 rear),rear 的索引记为 rear_pos。将 pivotrear 交换位置(即交换 '4' 和 '6')。 (pivot.key == 6pre_pos == 0rear_pos == 7,交换后数列为: 4, 2, 3, 7, 1, 5, 8, 6, 9

step3,现在,从数列头部开始,找到索引为 pre+1 的元素,以索引为 pre+1 的元素为起点,向数列尾部方向做遍历(为方便理解,以下称 '从左到右遍历')。直到找到比 pivot 大的元素(记为 pre),更新 p_pos 的值为 pre 当前的索引位置,交换 prepivot 的位置(即交换 '6' 和 '7')。(pivot.key == 6pre_pos == 3rear_pos == 7,交换后数列为: 4, 2, 3, 6, 1, 5, 8, 7, 9

到这里,我们发现,经过两次交换, prepre.key == 6)左侧的元素都比 pivot 小,rearrear.key == 7)右侧的元素都比 pivot 大。

重复 step2step3,完成第一趟排序,得到数列 4, 2, 3, 5, 1, 6, 8, 7, 9

经过第一趟排序,我们得到了两个新的数列 4, 2, 3, 5, 1(记为 数列 a) 和 8, 7, 9 (记为 数列 b)。显然,数列 a 中的元素都小于 pivotpivot.key == 6),而数列 b 中的元素都大于 piovt

这时候,我们分别以数列 a、 数列 b 为待排序数列,对它们进行快速排序的第一趟排序。

数列 a 经过第一趟排序,结果为 1, 2, 3, 4, 5,已经有序;数列 b 经过第一趟排序,结果为 7, 8, 9

这时候,原始的待排序数列中的所有元素已经是有序排列的了。即 1, 2, 3, 4, 5 + 6 + 7, 8, 9

此时,快速排序已完成。

你可能感兴趣的:(快速排序算法小记)