其他分享
首页 > 其他分享> > 排序之快速排序

排序之快速排序

作者:互联网

快速排序

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