排序之快速排序
作者:互联网
快速排序
1. 思路
快速排序顾名思义就是很快的排序,它的时间复杂度为 O(nlogn),空间复杂度也是 O(nlogn),它是一种不稳定的排序。
它为啥比插入排序、选择排序、冒泡排序快呢?
因为它可以一次性将主元元素放在合适的位置。主元是什么呢?
数组中主元左边的元素都比主元小,主元右边的元素都比主元大。
快速排序采用分治的思想,分别对主元左边的数组和主元右边的数组进行排序,直至所有元素都是排好序的。
2. 实现
首先我们需要找到主元,并将主元放在正确的位置上,使主元左边的元素都小于主元,主元右边的元素都大于主元。因此定义函数 int partition(vector<int>& arr, int left, int right)
,其中 arr 是待排数组,left 和 right 是两个指针,分别指向待排数组的最左端和最右端。
int partition(vector<int>& arr, int left, int right)
{
//选择数组最左端元素作为主元
int part = arr[left];
// left 等于 right 时,主元就被放置在了正确的位置上
while(left < right)
{
// 主元右端的元素大于主元,则 right 不断向左移动
while(left < right && arr[right] >= part)
{
right--;
}
// 否则,将主元右边小于主元的元素放在左边空位上
arr[left] = arr[right];
// 主元左端的元素小于主元,则 left 不断向右移动
if(left < right && arr[left] <= part)
{
left++;
}
// 否则,将主元左边大于主元的元素放在右边空位上
arr[right] = arr[left];
}
// 排序完毕,将主元复位
arr[left] = part;
// 返回主元位置
return left;
}
然后,由于主元已经被放在了正确的位置上,现在分别对主元左边的数组和主元右边的数组进行排序。定义 void quicksort(vector<int>& arr, int left, int right)
函数,分别递归主元左边的数组和主元右边的数组。递归的终止条件是数组完成排序,也就是说至少有两个元素,left < right
。
void quicksort(vector<int>& arr, int left, int right)
{
int pivot = partition(arr, left, right);
if(left < right)
{
quicksort(arr, left, pivot - 1);
quicksort(arr, pivot + 1, right);
}
}
对数组 arr 进行排序,left 和 right 分别为数组的左端和右端位置。quicksort 的调用如下:
quicksort(arr, 0, arr.size() - 1);
下面给出快速排序的完整实现:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型vector 待排序的数组
* @return int整型vector
*/
vector<int> MySort(vector<int>& arr) {
// write code here
quicksort(arr, 0, arr.size() - 1);
return arr;
}
void quicksort(vector<int>& arr, int left, int right)
{
int pivot = partition(arr, left, right);
if(left < right)
{
quicksort(arr, left, pivot - 1);
quicksort(arr, pivot + 1, right);
}
}
int partition(vector<int>& arr, int left, int right)
{
int part = arr[left];
while(left < right)
{
while(left < right && arr[right] >= part)
{
right--;
}
arr[left] = arr[right];
while(left < right && arr[left] <= part)
{
left++;
}
arr[right] = arr[left];
}
arr[left] = part;
return left;
}
};
3. 示例
给出一个使用快速排序数组的例子
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int partition(vector<int>& arr, int left, int right)
{
int part = arr[left];
while(left < right)
{
while(left < right && arr[right] >= part)
{
right--;
}
arr[left] = arr[right];
while(left < right && arr[left] <= part)
{
left++;
}
arr[right] = arr[left];
}
arr[left] = part;
return left;
}
void quicksort(vector<int>& arr, int left, int right)
{
int pivot = partition(arr, left, right);
if(left < right)
{
quicksort(arr, left, pivot - 1);
quicksort(arr, pivot + 1, right);
}
}
vector<int> MySort(vector<int>& arr) {
// write code here
quicksort(arr, 0, arr.size() - 1);
return arr;
}
void printarr(vector<int>& arr, string s)
{
cout << s << endl;
for(int i = 0; i < arr.size(); i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
int main()
{
int a[] = { 34, 8, 64, 51, 32, 21 };
vector<int> arr;
arr.insert(arr.begin(),a, a + 6);
printarr(arr,"before sort");
MySort(arr);
printarr(arr,"after sort");
return 0;
}
标签:arr,right,int,主元,vector,排序,快速,left 来源: https://blog.csdn.net/qq_39220334/article/details/120807285