快速排序也使用了分治法的思想,对给定的一组元素,首先用两个指针L,R分别指向最左边和最右边的元素,然后取出最左边的元素,从右边的指针指向的元素开始,和取出的元素比较,如果大于取出的元素,则放右边(如果本来就在右边,则不动),右边的指针向左移动再比较,如果小于取出的元素,则将这个元素放到左边(如果本来就在左边,则不动)。如果位置动了,则切换指针移动一位比较。当两个指针重合的时候,将取出的作为比较的元素放到重合的位置,这一轮比较就结束了,然后需要对重合指针左边的元素和右边的元素分别做上述操作,直到完成排序。
举个例子,假设有一组数6,2,8,1,0,9,4
首先用两个指针L,R分别指向这组数的最左边和最右边
然后取出左边第一个数字作为比较的数字,指针L指向的位置空出来了
然后从指针R指向的数字4开始和数字6比较
因为4比6小,所以将4放到左边L指向的空位置上
R指针指向的元素移动了,所以要切换到指针L向右移动一位,用指针L指向的2和数字6比较
因为2比6小,所以2放左边,2本来就在左边,所以2位置不动,继续将指针L向右移动一位,用指针指向的8和数字6比较
因为数字8比数字6大,所以要将数字8放右边,放到指针R指向的空位置上
指针L指向的元素移动了,所以要切换到指针R向左移动一位,用指针R指向的数字9和数字6比较
因为数字9大于数字6,所以数字9需要放右边,数字9本来就在右边,所以位置不动,让指针R继续左移一位,用指针R指向的数字0和数字6比较
因为数字0小于数字6,所以需要将数字0放到指针L指向的空位置
然后切换到指针L向右移动一位,用指针L指向的数字1和数字6比较
因为数字1比数字6小,所以数字1放左边,继续将指针L右移一位
这时候指针L和指针R重合了,将比较的数字6放到指针指向的空位置
这样第一轮排序就结束了
接下来对数字6左边的数字进行排序。同样的,指针L,R分别指向最左边和最右边的数字
将最左边的数字4取出来,作为比较的数字
从指针R指向的数字1开始和数字4比较
因为1小于4,所以将1放到指针L指向的位置
指针L向右移动一位,用指针L指向的数字2与数字4比较
因为2比4小,所以位置不动,继续向右移动指针L,用指针L指向的数字0和数字4比较
因为0小于4,所以位置不动,继续向右移动指针L,这时候指针L和指针R的位置重合了
将数字4放到指针重合的空位置
这一轮结束
接下来,对数字4左边的数字进行排序,将指针L和指针R分别指向最左边的数字1和最右边的数字0
取出最左边的数字1作为比较的数字
从指针R指向的数字0开始和1比较
因为数字0比数字1小,所以将1放到指针L指向的位置
然后指针L向右移动一位,用指针L指向的数字2和1比较
因为数字2比1大,所以将2放到指针R指向的位置
然后指针R向左移动一位
这时候指针L和指针R重合了,所以将数字1放到指针重合的位置
数字1左边和右边都只有一个数字,所以无需再对其排序了。前面数字4右边没有数字,所以无需对数字4右边排序,加上数字4,就是0,1,2,4,已经排好序了
再加上数字6,就是0,1,2,4,6
然后再对数字6右边的9和8执行同样的操作,指针L,R分别指向最左边的数字9和最右边的数字8
将最左边的数字9取出来,作为比较的数字
从指针R指向的数字8开始,和数字9比较
因为数字8小于数字9,所以将数字8放到指针L指向的位置
指针L向右移动一位
这时候指针L和指针R重合了,所以将数字9放到指针重合的位置
数字9左边只有一个数字,右边没有数字,所以排序完成了,加上前面排序好的数字,所以最终的结果是
总结
- 快速排序的最优时间复杂度和平均时间复杂度都是O(nlogn),最坏时间复杂度是O(n^2)
- 快速排序的最优空间复杂度是O(logn),最坏空间复杂度O(n)