快排

快速排序:时间复杂度O(N*logN) 额外空间复杂度O(logN)

在一个无序数组arr中,先选择数组的最后一个值作为划分值end,将数组arr中小于划分值的放在左边,等于划分值的放中间,大于划分值的放右边。
  可以通过时间复杂度O(N),额外空间复杂度O(1)完成上方的分组问题。首先假设两个虚拟组,左边是less组,有变量less指向less组的最右边位置,右边放more组,有变量more指向more组的最左边,其中划分值直接越过。然后有index从左至右逐个比较当前值与划分值的大小。
  1:如果当前值小于划分值,当前值与less+1位置的值交换,less++;index++;
  2:如果当前值等于划分值,直接index++;
  3:如果当前值大于划分值,当前值与more-1位置的值交换,more--;index不变;
  一直按照上面的分配规则,当index==more时令最后的划分值与more交换;
  然后可以得到小于划分值的在arr[0]~arr[less]中,大于划分值的在arr[more+1]~arr[length-1];
  然后左右分别递归,调用自己一直到index==end,就可以达到数组有序的目的。
public void quickSort(int[]arr){
   if(arr==null||arr.length<2){
       return;
   }
   quickSort(arr,0,arr.length-1);
}
public void quickSort(int []arr,int i,int j){
//递归是否进行的判断条件
  if(i<j){
  //随机快排  在i与j之间随机选择一个数与最后值交换,作为划分值,
  //如果划分值选择出现很大的偏差,最差时间复杂度为O(N^2),,所以使用随机快排时间复杂度为O(N*logN)
  swap(arr, i + (int) (Math.random() * (j - i + 1)), j);
     int[]p=partition(arr,i,j);
     //递归调用自己
     quickSort(arr,i,p[0]);
     quickSort(arr,p[1],j);
  }
}
//荷兰国旗问题
public void partition(int []arr,int i,int j){
   int less=i-1;
   int more=j;
   //单次排列是否进行的判断条件
   while(i<more){
   //按照规则排列
       if(arr[i]<arr[j]){
       swap(arr,++less,i++);
       }else if(arr[i]==arr[j]){
       i++;
       }else{
       swap(arr,--more,i);
       }
   } 
   swap(arr,more,j);
   //将more和less组的边界值返回,作为下一次的j和i
   return new int[]{less,more+1};
}
public void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;

时间复杂度: T(n)=2T(n/2)【划分成两个n/2规模的子问题】+O(N)【partition过程】

估计同样规模递归行为的时间复杂度:master公式

T(N)=aT(N/b)+O(N^d);
如果:
1  log(b,a)>d  T(N)为(N^(log(b,a));
2  log(b,a)==d  T(N)为(N^d*logN);
3  log(b,a)<d  T(N)为(N^d);

递归是将本身分成几个相同的小问题,调用自己的过程,而且在系统栈中是通过压栈和弹栈的方式实现的。把函数中申请的信息和运行到的行的信息压进栈,重复将子问题调用函数时的信息压入栈中,一直等到base case的触发然后依次弹栈,最后通过子问题的结果获得最终的结果。而父级函数按照栈中的记录继续向下运行。

额外空间复杂度O(logN)是在递归函数进入子函数时记录断点事需要的 而不是在partition函数中需要的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值