思路:
快速排序和前面介绍的三种排序的框架不太一样,不分已排序和未排序。其主要是选定一个值,这个值通常是第一个元素,然后将数组元素小于这个值放在左边,大于这个值的放在右边。将左右两部分看作两个数组,重复刚才的步骤,直到不能再分为止。
注意:将数组元素分成两部分的操作,是通过遍历比较,并且交换的方式实现。
详细排序过程:
待排序数据: 4,7,0,2,8,1 (将第一个元素作为选定值)
1,7,0,2,8,4 (从后往前遍历,遇到比 4 小的数1,并交换)
1,4,0,2,8,7(从前往后遍历,遇到比 4 大的数7, 并交换)
然后继续,知道分成两个子数组,左边小于右边为止:
1,2,0,4,8,7(从后往前遍历,遇到比 4 小的数2,并交换)
1,2,0,4,8,7(从前往后遍历,没有遇到 比大的4,不变 )
以上就是一次快速排序的过程,下面继续将两个子数组单独排序
待排序数据: 1,2,0 (将第一个元素作为选定值)
0,2,1 (从后往前遍历,遇到比1 小的数0,并交换)
0,1,2 (从前往后遍历,没有遇到比1大的)
待排序数据: 8,7 (将第一个元素作为选定值)
7,8 (从后往前遍历,遇到比8 小的数7,并交换)
7,8 (从前往后遍历,没有遇到比8大的)
最后排序的 结果是:
0,1,2,4,7,8
由此可知: 快速排序就是不断将数组划分为左右两个子数组,这两个数组左边小于右边,当划分的最小时可以获得有序的数组。
实现代码如下:
#include<iostream>
#include<vector>
int main()
{
vector<int> A = { 4,7,0,2,8,1 };
quickSort(A, 0, A.size() - 1);
return 0;
}
void quickSort(vector<int> &nums, int i, int j) // i,j 是排序的数组开始和结束索引
{
if (i >= j) { //边界条件,最小时(只有一个元素)返回
return;
}
int key = i, temp, oldKey;
while (true) {
oldKey = key;
for (int k =j; k > key; k--) { // 从后往前遍历
if (nums[k] < nums[key]) { // 遇到比 选定值 小的交换
temp = nums[k];
nums[k] = nums[key];
nums[key] = temp;
key = k;
}
}
for (int k = i; k < key; k++) { // 从前往后遍历
if (nums[k] > nums[key]) { // 遇到比 选定值 大的交换
temp = nums[k];
nums[k] = nums[key];
nums[key] = temp;
key = k;
}
}
if (oldKey == key) { // 当两次遍历下来索引没有变动,说明已经完成一次排序,跳出循环
break;
}
}
quickSort(nums, i, key - 1); // 递归,左数组排序(如上面的0,2,1)
quickSort(nums, key + 1,j); // 递归,右数组排序(如上面的8,7)
}
结尾:
想了解其他排序可点击这里:排序算法总结