快速排序算法思想
Quick Sort is also based on the concept of Divide and Conquer, just like merge sort. But in quick sort all the heavy lifting(major work) is done while dividing the array into subarrays, while in case of merge sort, all the real work happens during merging the subarrays. In case of quick sort, the combine step does absolutely nothing.
就像合并排序一样,快速排序也基于分而治之的概念。 但是在快速排序中,所有繁重的工作(繁重的工作)都是在将数组划分为子数组时完成的,而在合并排序的情况下,所有实际工作都是在合并子数组时发生的。 在快速分类的情况下,合并步骤绝对不执行任何操作。
It is also called partition-exchange sort. This algorithm divides the list into three main parts:
也称为partition-exchange sort 。 此算法将列表分为三个主要部分:
Elements less than the Pivot element
小于枢轴元素的元素
Pivot element(Central element)
枢轴元素(中央元素)
Elements greater than the pivot element
大于枢轴元素的元素
Pivot element can be any element from the array, it can be the first element, the last element or any random element. In this tutorial, we will take the rightmost element or the last element as pivot.
Pivot元素可以是数组中的任何元素,可以是第一个元素,最后一个元素或任何随机元素。 在本教程中,我们将最右边的元素或最后一个元素作为数据透视表 。
For example: In the array {52, 37, 63, 14, 17, 8, 6, 25}
, we take 25
as pivot. So after the first pass, the list will be changed like this.
例如:在数组{52, 37, 63, 14, 17, 8, 6, 25}
,我们将25
作为支点 。 因此,第一次通过后,列表将像这样更改。
{6 8 17 14
25 63 37 52
}
{ 6 8 17 14
25 63 37 52
}
Hence after the first pass, pivot will be set at its position, with all the elements smaller to it on its left and all the elements larger than to its right. Now 6 8 17 14
and 63 37 52
are considered as two separate sunarrays, and same recursive logic will be applied on them, and we will keep doing this until the complete array is sorted.
因此,在第一遍之后,枢轴将被设置在其位置,所有元素在其左侧均较小 ,所有元素均大于其右侧。 现在将6 8 17 14
和63 37 52
视为两个独立的太阳阵列,并且将对它们应用相同的递归逻辑,我们将继续这样做,直到对整个阵列进行排序为止。
快速排序如何工作? (How Quick Sorting Works?)
Following are the steps involved in quick sort algorithm:
以下是快速排序算法中涉及的步骤:
After selecting an element as pivot, which is the last index of the array in our case, we divide the array for the first time.
在选择一个元素作为ivot之后 ,这是本例中数组的最后一个索引,我们第一次对数组进行分割。
In quick sort, we call this partitioning. It is not simple breaking down of array into 2 subarrays, but in case of partitioning, the array elements are so positioned that all the elements smaller than the pivot will be on the left side of the pivot and all the elements greater than the pivot will be on the right side of it.
快速地将其称为分区 。 将数组分解成2个子数组并非易事,但在分区的情况下,数组元素的位置应使所有小于枢轴的元素都位于枢轴的左侧,而所有大于枢轴的元素都将位于左侧。在它的右边。
And the pivot element will be at its final sorted position.
枢轴元素将处于其最终排序位置。
The elements to the left and right, may not be sorted.
左侧和右侧的元素可能未排序。
Then we pick subarrays, elements on the left of pivot and elements on the right of pivot, and we perform partitioning on them by choosing a pivot in the subarrays.
然后,我们选择子数组, 数据透视图左侧的元素和数据透视图右侧的元素,然后通过在子数组中选择数据透视图对其进行分区 。
Let's consider an array with values {9, 7, 5, 11, 12, 2, 14, 3, 10, 6}
让我们考虑一个值为{9, 7, 5, 11, 12, 2, 14, 3, 10, 6}
9,7,5,11,12,12,2,14,3,10,6 {9, 7, 5, 11, 12, 2, 14, 3, 10, 6}
的数组
Below, we have a pictorial representation of how quick sort will sort the given array.
下面,我们以图形方式表示如何快速排序给定数组。
![How Quick Sort algorithm works](https://i-blog.csdnimg.cn/blog_migrate/ee443d2555b5e6bd4c3a0f45e7297f4e.png)
In step 1, we select the last element as the pivot, which is 6
in this case, and call for partitioning
, hence re-arranging the array in such a way that 6
will be placed in its final position and to its left will be all the elements less than it and to its right, we will have all the elements greater than it.
在第1步中,我们选择最后一个元素作为支点 ,在这种情况下为6
,并调用partitioning
,因此以这样的方式重新排列数组:将6
放置在其最终位置,并将其放置在左侧所有元素都小于它,并且在它的右边,我们将拥有所有大于它的元素。
Then we pick the subarray on the left and the subarray on the right and select a pivot for them, in the above diagram, we chose 3
as pivot for the left subarray and 11
as pivot for the right subarray.
然后,我们在左侧选择子阵列,在右侧选择子阵列,并为其选择一个枢轴 ,在上图中,我们选择3
作为左侧子阵列的枢轴,选择11
作为右侧子阵列的枢轴。
And we again call for partitioning
.
然后我们再次要求partitioning
。
实现快速排序算法 (Implementing Quick Sort Algorithm)
Below we have a simple C program implementing the Quick sort algorithm:
下面我们有一个简单的C程序,实现了快速排序算法:
// simple C program for Quick Sort
#include <stdio.h>
int partition(int a[], int beg, int end);
void quickSort(int a[], int beg, int end);
void main()
{
int i;
int arr[10]={90,23,101,45,65,28,67,89,34,29};
quickSort(arr, 0, 9);
printf("\n The sorted array is: \n");
for(i=0;i<10;i++)
printf(" %d\t", arr[i]);
}
int partition(int a[], int beg, int end)
{
int left, right, temp, loc, flag;
loc = left = beg;
right = end;
flag = 0;
while(flag != 1)
{
while((a[loc] <= a[right]) && (loc!=right))
right--;
if(loc==right)
flag =1;
else if(a[loc]>a[right])
{
temp = a[loc];
a[loc] = a[right];
a[right] = temp;
loc = right;
}
if(flag!=1)
{
while((a[loc] >= a[left]) && (loc!=left))
left++;
if(loc==left)
flag =1;
else if(a[loc] < a[left])
{
temp = a[loc];
a[loc] = a[left];
a[left] = temp;
loc = left;
}
}
}
return loc;
}
void quickSort(int a[], int beg, int end)
{
int loc;
if(beg<end)
{
loc = partition(a, beg, end);
quickSort(a, beg, loc-1);
quickSort(a, loc+1, end);
}
}
![output-quick-sort](https://i-blog.csdnimg.cn/blog_migrate/4f612264c1783982a79a1dd681bb8b74.png)
快速排序的复杂性分析 (Complexity Analysis of Quick Sort)
For an array, in which partitioning leads to unbalanced subarrays, to an extent where on the left side there are no elements, with all the elements greater than the pivot, hence on the right side.
对于其中分区导致不平衡子数组的阵列,在某种程度上,左侧没有元素,所有元素都大于支点 ,因此在右侧。
And if keep on getting unbalanced subarrays, then the running time is the worst case, which is O(n2)
而且如果继续获取不平衡的子数组,则运行时间是最坏的情况,即O(n 2 )
Where as if partitioning leads to almost equal subarrays, then the running time is the best, with time complexity as O(n*log n).
好像分区导致几乎相等的子数组一样,那么运行时间是最好的,时间复杂度为O(n * log n) 。
Worst Case Time Complexity [ Big-O ]: O(n2)
最坏情况下的时间复杂度[Big-O]: O(n 2 )
Best Case Time Complexity [Big-omega]: O(n*log n)
最佳情况下的时间复杂度[Big-Omega]: O(n * log n)
Average Time Complexity [Big-theta]: O(n*log n)
平均时间复杂度[Big-theta]: O(n * log n)
Space Complexity: O(n*log n)
空间复杂度: O(n * log n)
As we know now, that if subarrays partitioning produced after partitioning are unbalanced, quick sort will take more time to finish. If someone knows that you pick the last index as pivot all the time, they can intentionally provide you with array which will result in worst-case running time for quick sort.
众所周知,如果分区后产生的子数组分区不平衡,则快速排序将花费更多时间来完成。 如果有人知道您一直都在选择最后一个索引作为枢轴 ,那么他们可以有意为您提供数组,这将导致最坏情况下的运行时间,从而无法进行快速排序。
To avoid this, you can pick random pivot element too. It won't make any difference in the algorithm, as all you need to do is, pick a random element from the array, swap it with element at the last index, make it the pivot and carry on with quick sort.
为了避免这种情况,您也可以选择随机枢轴元素。 它不会对算法造成任何影响,因为您所需要做的就是从数组中选择一个随机元素,将其与最后一个索引处的元素交换,使其成为枢轴并进行快速排序。
Space required by quick sort is very less, only
O(n*log n)
additional space is required.快速排序所需的空间非常少,仅需要
O(n*log n)
额外的空间。Quick sort is not a stable sorting technique, so it might change the occurence of two similar elements in the list while sorting.
快速排序不是一种稳定的排序技术,因此它可能会改变排序时列表中两个相似元素的出现。
翻译自: https://www.studytonight.com/data-structures/quick-sort
快速排序算法思想