快速排序思路(Java、C++)

快速排序

复杂度

最优的情况下空间复杂度为: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 29. 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;
 }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值