快速排序
复杂度
最优的情况下空间复杂度为:O(logN)
最差的情况下空间复杂度为:O(N^2)
快速排序的平均时间复杂度是:O(N*logN)
思路
将第一个位数设为基数temp,
先从最后一个下向左进行和基数的比较,
再从第一个下标0向右进行和基数的比较。
最终分成两部分,左边的都比基数小,右边的都比基数大,再分别对这两部分进行快排
要排序: 6 3 4 9 2 5 1
分别对应下标,,0 1 2 3 4 5 6
1. 基数为6,a[6]=1比基数小,交换,为:1 3 4 9 2 5 6
2. 从前往后比,a[0]=1小于基数6,
3. 直到a[3]=9比基数大,交换,为:1 3 4 6 2 5 9
4. 从后往前比,a[6]=9比基数大,a[5]=5比基数小,交换,为:1 3 4 5 2 6 9
5. 此时根据基数6分成了两部分,一部分小于,一部分大于等于
6. 分别对这两部分再进行快排操作,
7. 只写过程得到的结果:
8. 1 3 4 5 2 根据基数 1 分为 1 和3 4 5 2,
9. 3 4 5 2 继续分为 2 3 4 5
10.结合在一起就是 1 2 3 4 5 6 9
C++代码
//
// Created by Night on 2020/7/14.
//
#include <iostream>
#include <algorithm>
using namespace std;
int a[100];
void Quick_Sort(int *a,int begin,int end){
if(begin>end)
return;
int temp=a[begin];
int i=begin,j=end;
while (i!=j){
while (a[j]>=temp&&i<j)
j--;
swap(a[i],a[j]);
while (a[i]<=temp&&i<j)
i++;
swap(a[i],a[j]);
}
Quick_Sort(a,begin,i-1);
Quick_Sort(a,i+1,end);
}
int main(){
int n,k=0;
printf("排序前:");
while (scanf("%d",&n)){
a[k++]=n;
if(getchar()=='\n')
break;
}
Quick_Sort(a,0,k-1);
printf("排序后:");
for (int i = 0; i <k ; ++i) {
printf("%d ",a[i]);
}
return 0;
}
Java代码
public static void QuickSort(int[] nums, int left, int right) {
if (left >= right) {
return;
}
int pivot = partition(nums, left, right);
System.out.println("排序的结果 " + Arrays.toString(nums));
// 基准元素一定比左边的数大,所以左边分区最大值是:pivot - 1,分区范围是[left, pivot - 1]
QuickSort(nums, left, pivot - 1);
// 基准元素一定比右边的数小,所以右边分区最小值是:pivot + 1,分区范围是[pivot + 1, right]
QuickSort(nums, pivot + 1, right);
}
public static int partition(int[] nums, int left, int right) {
int pivotValue = nums[left]; // 存放基数
while (left < right) { // 终止条件left和right相遇
// 找到右边第一个小于基数的数
while (left < right && nums[right] >= pivotValue)
// 未找到,继续往前找
right--;
// 找到了就将right上的插入left位置,right位置视为空
nums[left] = nums[right];
// 找到左边第一个大于基数的数
while (left < right && nums[left] <= pivotValue)
// 未找到,继续往后找
left++;
// 找到了就将left上的插入right位置,left位置视为空
nums[right] = nums[left];
}
// left和right相遇了,将基数放到这个位置,左边的都小于等于,右边的都大于等于
nums[left] = pivotValue;
return left;
}