给定一个序列:22 33 49 47 33' 12 68 29
ios
进行快速排序算法
从序列中,任选一个记录k
做为轴值 pivot
数组
选择策略:ui
将剩余的元素,分割成 左子序列 L 和 右子序列 Rspa
L 中全部元素都 < k, R 中全部元素都 > k指针
对 L 和 R递归进行快排,直到子序列中有 0 个 或者 1 个元素,退出code
初始数组:排序
选定47
为轴值pivot
递归
pivot
与最后一个值29
进行交换(把pivot
放到最后面)string
接下来,以pivot=47
为界,分红左子序列 L
和右子序列 R
比47
大的都放在右边,比47
小的都放在左边(用的交换)
遍历数组
left
和right
left != right
的时候
arr[left]
的,小于等于pivot
,且left < right
的时候,left
右移
left
和right
未相遇,把left
的值赋给right
对应的值arr[right] = arr[left]
left
指针中止移动,轮到right
移动arr[right]
的值,大于等于pivot
,且right > left
的时候,right
左移
left
和right
未相遇。把right
的值赋给left
对应的值arr[left] = arr[right]
right
指针中止移动,轮到left
移动pivot
保存pivot=47
和最后一个值互换
22 <= 47
,left
向右移动
33 <= 47
,left
向右移动
49 > 47
,不知足arr[left] <= pivot
把left
的值赋给right
arr[right] = arr[left]
赋值事后,left
不动,right
向左移动
68 >= 47
,right向左移动
12 < 47
,不知足arr[right] >= pivot
把right
的值赋给left
arr[left] = arr[right]
赋值事后,right
不动,left
向右移动
29 < 47
,left
向右移动
33' < 47
,left
向右移动
向右移动后,left == right
,退出循环
将pivot
赋给arr[left]
至此,第一轮分割序列完成
通过第一轮分割,47
左边的是左子序列,右边是右子序列
第二轮对左子序列分割,选择中间值做为pivot
12和33'
进行交换
22 > 12
,不知足arr[left] <= pivot
把arr[left]
赋给arr[right]
arr[right] = arr[left]
赋值事后,left
不动,right
向左移动
2九、33'、33
都比12
大,因此right
一直移动到下图位置
33 > 12
,right
继续向左移动
此时right == left
,终止循环
把pivot
赋给arr[left]
至此,左子序列1也分割完成了
快排就是一个递归的过程,分割获得左子序列
再对左子序列进行快排分割,获得左子序列的左子序列....
处理完左边,再去处理右边的右子序列
右子序列只有4七、6八、49
,选择48
做为轴值 pivot
pivot
和最后一个值交换
4七、49
都比pivot=68
小,left
一直向右移动,直到left == right
分割以后,只剩下左子序列:4七、49
4七、49
,选49
做为轴值,获得左子序列47
子序列只剩下一个元素47
,就没必要排序了,右边排序结束
结果:4七、4九、68
选择中间的值做为轴值
#include <iostream> #include <vector> #include <algorithm> #include <unordered_map> #include <unordered_set> #include <string> #include <stack> #include <cmath> #include <map> using namespace std; /** * * @param arr 待分割的序列 * @param left 左边界 * @param right 右边界 * @return 分割后轴值的位置 */ template<class T> int PartitionArr(vector<T>& arr, int left, int right) { T temp = arr[right]; while (left != right) { while (arr[left] <= temp && left < right) { left++; } if (left < right) { arr[right] = arr[left]; // 赋值后,left不动,right向左移 right--; } while (arr[right] >= temp && right > left) { right--; } if (left < right) { arr[left] = arr[right]; // 赋值后,right不动,left向右移 left++; } } // 当left == right,把轴值放回left上 arr[left] = temp; return left; } /** * * @param arr 待排序数组 * @param left 左边界 * @param right 右边界 */ template<class T> void quickSort(vector<T>& arr, int left, int right) { // 子序列剩下0或1个元素,排序结束 if (right <= left) { return; } // 选择数组中间做为轴值 int pivot = (left + right) / 2; // 把轴值放到数组最后面 swap(arr[right], arr[pivot]); // 分割后轴值的位置 // 分割后,左边值 < 轴值 < 右边值 pivot = PartitionArr(arr, left, right); quickSort(arr, left, pivot - 1); quickSort(arr, pivot + 1, right); } int main() { vector<int> arr = { 22,33,49,47,33,12,68,29 }; for (auto& i : arr) { cout << i << ' '; } cout << endl << endl; quickSort(arr, 0, arr.size() - 1); for (auto& i : arr) { cout << i << ' '; } cout << endl << endl; system("pause"); return 0; }
快排是不稳定的排序算法
33 33'
排序后可能变成33' 33
时间复杂度:
空间复杂度: