「改进的快速排序」时间复杂度接近O(n)

来源:互联网 发布:icloud照片怎么导入mac 编辑:程序博客网 时间:2024/06/11 21:30

1.快速排序知识点回顾:

快速排序采用了一种分治的策略,通常称其为分治法(Divide-and-Conquer)。

平均时间复杂度为:O(nlogn)

        最好时间复杂度为:O(nlogn), 每次找的基准数最佳,为每个区间的中值。

        最坏时间复杂度为:O(n2), 数组递增或者递减。

空间复杂度:快速排序在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为 O(lgn), 故递归后所需栈空间为 O(lgn) 。最坏情况下,递归树的高度为 O(n), 所需的栈空间为 O(n) 

该方法的基本思想是:

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

快速排序代码:

int partition(int arr[], const int& left, const int& right){    if(left < right)    {        medianAsPivot(arr, left, right);        int i = left;        int j = right;        int key = arr[i]; // 首元素作为pivot        while(i < j)        {            while(i<j && arr[j]>=key) j--;            if(i < j) arr[i++] = arr[j];            while(i<j && arr[i]<key) i++;            if(i < j) arr[j--] = arr[i];        }        arr[i] = key;        return i;    }    return left;}// 快速排序递归实现void quickSort(int arr[], const int& left, const int& right){    if(left < right)    {        int p = partition(arr, left, right);        quickSort(arr, left, p-1);        quickSort(arr, p+1, right);    }}

2.Kth Largest Element

http://www.lintcode.com/en/problem/kth-largest-element/

要接近O(n)的解法,必须每次选择区间的中值最为基准值。

void adjustPivot(vector<int> &nums, int left, int right){    int middle = (left & right) + ((left ^ right) >> 1);    if(nums[middle] >= min(nums[left], nums[right]) && nums[middle] <= max(nums[left], nums[right]))        swap(nums[left], nums[middle]);    else if(nums[right] >= min(nums[left], nums[middle]) && nums[right] <= max(nums[left], nums[middle]))        swap(nums[left], nums[right]);}int partition(vector<int> &nums, int left, int right){    if(left < right)    {        adjustPivot(nums, left, right);        int pivot = nums[left];        while(left < right)        {            while(left < right && nums[right] > pivot)                 right--;            if(left < right) nums[left++] = nums[right];            while(left < right && nums[left] <= pivot)                 left++;            if(left < right) nums[right--] = nums[left];        }        nums[left] = pivot;    }    return left;}int kthLargestElement(int k, vector<int> nums){    int size = nums.size();    if(k <= 0 || k > size)         return -1;    int left = 0;    int right = size - 1;    while(true)    {        int position = partition(nums, left, right);        if(position < size-k) left = position + 1;         else if(position > size-k) right = position - 1;        else return nums[size - k];    }}




0 0