1.快速排序的思路(从小->大)
快速排序在开始时,都会取一个序列最左边的数作为一个key值,目的就是调整序列------把比key值小的数放到key的左边,比key大的数放到key的右边。
然后再以key值的位置为界,key值位置以左的作为一个序列,key值位置以右的又作为一个序列,再在新序列中重复上面的操作。
如:
0 | 1 | 2 | 3 | 4 |
4 | 6 | 1 | 5 | 2 |
首先,4作为key值,第一轮把4放在序列的中间位置,比4小的在4的左边,比4大的在4的右边,得:(为什么排成这样先不用理,等等介绍)
0 | 1 | 2 | 3 | 4 |
2 | 1 | 4 | 5 | 6 |
然后再以4以左的新序列重复上述操作,再以4已右的新序列重复上面的操作。就是一直把各个序列的第一个数放到合适的位置,来排序整个序列。
4以左的序列,key=2:
0 | 1 |
2 | 1 |
排完后就是1,2.
以右的序列一样道理
具体方法:(小--->大)
以序列: 4,6,1,5,2 为例
0 | 1 | 2 | 3 | 4 |
4 | 6 | 1 | 5 | 2 |
有两个标记位置的变量 left 和 right。
left一开始指向最左边,就是left = 0,right指向最右边,right = 4
key 一开始等于 序列左边的数,所以key = 4.
然后就得到第一轮的值:
0 | 1 | 2 | 3 | 4 |
2 | 1 | 4 | 5 | 6 |
可以看到比4小的值已经全部丢到4的左边去,比4大的值也全部被丢到4的右边去
最后分别在左边序列 和 右边序列递归重复上面的操作就可以了。
代码:
版本1:
def QuickSort(a,left,right):
if left>right:
return
i = left
j = right
key = a[left]
while i!=j: #左、右指针重合时结束
#先从右向左扫描
while i<j and a[j]>=key:
j-=1
#再从左向右扫描 顺序一定要先从右开始,否则会错
while i<j and a[i]<=key:
i+=1
t1 = a[i]
a[i] = a[j]
a[j] = t1
#当 i = j时,盖位置的值与a[left]交换
t2 = a[i]
a[i] = a[left]
a[left] = t2
QuickSort(a,left,i-1)
QuickSort(a,i+1,right)
return a
l = [3,1,2,5,9]
res = QuickSort(l,0,len(l)-1)
print(res) #[1, 2, 3, 5, 9]
3. 时间复杂度
快速排序的时间复杂度是分最优情况和最坏情况的。
最优情况:O(nlogn)
最坏情况:O(n^2)
解释:
快速排序的一次划分算法从两头交替搜索,直到left和right重合,因此其时间复杂度是O(n);但整个快速排序算法的时间复杂度与划分的趟数有关。
最优情况:理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过log2n趟划分,便可得到长度为1的子表。这样,整个算法的时间复杂度为O(nlog2n)。
最差情况:每次所选的中间数是当前序列中的最大或最小元素,这使得每次划分所得的子表中一个为空表,另一子表的长度为原表的长度-1。这样,长度为n的数据表的快速排序需要经过n趟划分,使得整个排序算法的时间复杂度为O(n^2)
更简洁的版本2:
def QuickSort(a):
if len(a)<2:
return a
else:
key = a[0]
less = [i for i in a[1:] if i <=key]
geater = [i for i in a[1:] if i > key]
return QuickSort(less)+[key]+QuickSort(geater)
l = [3,1,2,5,9]
res = QuickSort(l)
print(res) #[1, 2, 3, 5, 9]
Java版本代码:
public class QuickSort {
public static void quickSort(int[] arr,int left,int right){
if(left>=right) return;
int i = left;
int j = right;
int key = arr[left];
while(i!=j){
while(i<j && arr[j]>=key){
j--;
}
while(i<j && arr[i]<=key){
i++;
}
if(i!=j){
int t = arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
arr[left]=arr[i];
arr[i]=key;
quickSort(arr,left,i-1);
quickSort(arr,i+1,right);
}
public static void main(String[] args) {
int[] arr = {3,2,1,4,2,3,1};
quickSort(arr,0,arr.length-1);
String str="";
for(int a:arr){
str+=a;
}
System.out.println(str);//1122334
}
}