快速排序
第一种思路
算法描述:快速排序首先选择数组第一个元素为基准元素,从游标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));
}
}
1307

被折叠的 条评论
为什么被折叠?



