分治与递归之快速排序

快速排序

第一种思路
算法描述:快速排序首先选择数组第一个元素为基准元素,从游标1从第2个元素开始,游标2从最后一个元素开始扫描,但游标1找到比基准元素大,停止扫描,游标2开始扫描,找到比基准元素小的元素,停止扫描,交换两个元素,以此类推,但游标1的下标大于或等于游标2,则基准元素与当前游标2为下标的元素交换,第一趟排序结束。而后数组被分为三部分。继续对左右子数组进行同样操作,最后合并。
代码描述:

public class QuickSort{
   pubilc static void quicksort(int[] arr,int left,int right)
   {
   if(left<right)
   {
   int m=partition(arr,left,right);//查找每一趟选择交换后的中间元素。
   quicksort(arr,left,m-1);//对左边数组进行快排操作
   quicksort(arr,m+1,right);//对右边数组进行快排操作

   }
   }
   public static int partiton(int[] arr,int left,int right)
   {
   int temp=arr[left];//基点
   int start=left+1;
   while(true)
   {
   while(arr[start]<=temp&&start<right)
   {
   start++;
}
   while(arr[right]>=temp&&strat<=right)
   {
   right--;
}
   if(start<right)//进行交换
{
   int tem=0;
   tem=arr[start]
   arr[start]=arr[right]
   arr[right]=tem;
}
else break;
   }
   //确定了基准元素的位置
   arr[left]=arr[right];
   arr[rigth]=temp;
   return right;
}
public static void main(String[] args) {
int [] arr={8,4,3,7,1,5,6,2};
quicksort(arr,0,arr.length-1);
System.out.print(Arrays.toString(arr));
}
}

第二种思路:以数组第一个元素为基准,游标j从后面开始扫描,当找到比基准元素小的元素,将a[j]赋值给a[i],此时游标i从前面开始扫描,当找到比基准元素大的元素,将当前的a[i]赋值给a[j],依次类推,到最外层循环结束,将基准元素赋值给a[i],一次快速排序结束。后面也类似。
代码:

public class QuickSort2 {
 public static void quicksort2(int[] arr,int left,int right)
 {
  if(left<right)
  {
   int middle=partition(arr,left,right);//将数组划分成三部分
   quicksort2(arr,left,middle-1);//对左边数组进行递归排序
   quicksort2(arr,middle+1,right);//对右边数组进行递归排序
  }
 }
 public static int partition(int[] arr,int i,int j)
 {
 int temp=arr[i];//以每段数组第一个元素作为基点
  while(i<j)
  {
   while(i<j&&temp<=arr[j])
   {
    j--;
   }
   if(i<j) {
    arr[i]=arr[j];
    i++;
   }
   while(i<j&&temp>arr[i])
   {
    i++;
   }
   if(i<j)
   {
    arr[j]=arr[i];
    j--;
   }
   }
   arr[i]=temp;
  return i;

  }
   public static void main(String[] args) {
  // TODO Auto-generated method stub
  int [] arr={8,4,3,7,1,5,6,2};
  quicksort2(arr,0,arr.length-1);
  System.out.print(Arrays.toString(arr));
  }}

快速排序最好的情况下,将规模为n的问题分解为两个规模为n/2的子问题。时间复杂度为O(nlogn);
快速排序的执行效率取决于基准元素的选择,如果给点的数组本身就有序,那么每次选择第一个元素为基准元素,就会出现划分不平衡的情况,最坏时间复杂度为O(n的平方);可采用平衡快速排序法和基于随机支点选择的快速排序法。
平衡快速排序:取数组开头、中间和结尾的元素,在三个元素中取中值元素,将中值元素作为基准元素。
基于随机支点选择:取数组中的随机元素为基准元素。
随机支点选择的代码:

public class RandomQuicksort {
 public static void randomquicksort(int[]a,int low,int high)
 {
 if(low<high)
  {
   int k=randompartition(a,low,high);
   randomquicksort(a,low,k-1);
   randomquicksort(a,k+1,high);
  }
  }
 public static int randompartition(int[] a,int low,int high)
 {
  int temp;
  int n=(int) (low+Math.random()*(high-low+1));//取下标为low到high之间的随机元素。
  exchange(a,low,n);
  temp=a[low];
  while(low<high)
  {
   while(low<high&&a[high]>=temp)
   {
    high--;
   }
   if(low<high)
   {
    a[low]=a[high];
    low++;
   }
   while(low<high&&a[low]<=temp)
   {
    low++;
   }
   if(low<high)
   {
    a[high]=a[low];
    high--;
   }
  }
   a[low]=temp;
    return low;
  
 }
 public static void exchange(int[] a,int i,int j)//将随机选取的基点元素放在首位
 {
 int tem=a[i];
  a[i]=a[j];
  a[j]=tem;
 }
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  int [] arr={8,4,3,7,1,5,6,2};
  randomquicksort(arr,0,arr.length-1);
  System.out.print("随机支点快速排序"+Arrays.toString(arr));
  }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值