快速排序
1、快速排序的框架:找基准值–》按基准值将区间划分为两部分:左侧部分<基准值<右侧部分
递归排基准值左侧部分
递归排基准值右侧部分
public static void quickSort(int[] array,int left,int right){
if(right-left>1){
int div=pation3(array,left,right);
quickSort(array,left,div);//左闭右开区间
quickSort(array,div+1,right);
}
}
2、按照基准值分割区间的方式:
(1)Hoare
Hoare是发明这种排序算法的人名,取数组最后一个数为基准值,设置两个下标在数组的两端,begin从前往后找,遇到比基准值大的数停止,end是从后往前找比基准值小的数,然后交换以begin和end为下标的数,当begin不小于end时说明分割完毕,交换以begin和right-1为下标的数,最后返回begin的值
public static int partion1(int[] array,int left,int right){
int begin=left;
int end=right-1;
int key=array[end];
while (begin<end){
while (begin<end&&array[begin]<=key){
begin++;
}
while (begin<end&&array[end]>=key){
end--;
}
swap(array,begin,end);
}
if(begin!=right-1){
swap(array,begin,right-1);
}
return begin;
}
2、挖坑法
取最后一个元素为基准值,基准值的位置是坑,设置两个下标在数组的两端,begin从前往后找,遇到比基准值大的数停止,将这个是填到坑的位置;这时坑的位置是begin所在的位置,end往前找,找到比基准值小的数停止,把该数填充到坑的位置,这时end所在的位置是新的坑的位置。重复之前的操作,直到begin不小于end,最后把基准值填到begin的位置,返回begin的值
public static int partion2(int[] array,int left,int right){
int begin=left;
int end=right-1;
int key=array[end];
while (begin<end){
while (begin<end&&array[begin]<key){
begin++;
}
if(begin<end){
array[end--]=array[begin];
}
while (begin<end&&array[end]>key){
end--;
}
if (begin<end){
array[begin++]=array[end];
}
}
array[begin]=key;
return begin;
}
3、前后索引
还是取最后一个元素为基准值,设置两个索引,cur设置在数组开头,prev为cur-1;cur往后找,遇到比基准值小的数停止(注意:和前面两个方法不同,这里是找比基准值小的数),此时判断prev+1与cur是否相等,如果不等,交换以prev和cur下标的元素;如果相等则cur继续往后找。cur超过数组下标范围时停止,判断++prev是否为最后一个元素,如果不是就和最后一个元素交换。这时我们发现,prev左侧的元素都比基准值小,prev右侧的都比基准值大,返回prev。
public static int partion3(int[] array,int left,int right){
int cur=left;
int prev=cur-1;
int key=array[right-1];
while (cur<right){
if(array[cur]<key&&++prev!=cur)//prev的++操作肯定会执行
swap(array,cur,prev);
cur++;
}
if(++prev!=right-1){
swap(array,prev,right-1);
}
return prev;
}
冒泡排序
在无序区间,通过相邻数比较,将最大的数冒泡到无序区间最后,持续此过程直到区间有序
public static void bullonbSort(int[] array){
int n=array.length;
for(int i=0;i<n;i++){
boolean flag=false;
for(int j=0;j<n-i-1;j++){
if(array[j]>array[j+1]){
int tmp=array[j];
array[j]=array[j+1];
array[j+1]=tmp;
flag=true;
}
}
if(!flag){
break;
}
}
}
设置标志位flag,如果一趟跑完没有交换过数据,说明数组有序,直接跳出返回