一、基本思想
选定一个元素称为主元,遍历整个数组,将大于等于主元的放在主元的右边,将小于主元的放在主元 的左边,此时,主元的位置便是确定的了。将主元分为左右两部分,进行递归遍历。
例:数组arr[]={4,1,3,2,7,6,8};
选定一个元素作为主元
遍历数组,将大于等于主元的元素放于主元的右边,小于主元的元素放于主元的左边。
此时主元已经处于有序的位置,再将左右两部分分离,分别选取主元,分别递归,以此类推
代码:
static void quicksort(int a[],int left,int right)
{
int center;
// int i,j;
// int temp;
if(left<right)
{
center=partion(a,left,right);
System.out.println("center:"+center);
if(left<center-1)
{
quicksort(a,left,center-1);
}
if(center+1<right)
{
System.out.println("center+1~right");
quicksort(a,center+1,right);
}
}
else return ;
}
二、分割操作
1.单向调整
设最后的一个元素为主元,数组arr的范围是[left,right].
设置两个变量i,j,都指向数组的left的下标
j从左向右进行遍历,遇到比主元小的元素,将其与i下标对应的元素进行交换,同时i++。
交换之后,j++继续向右遍历,以此类推,遍历到j=right
当j遍历到right下标对应的元素之后,将i指向的元素与主元进行交换。
public static int partion(int a[],int left,int right)
{
int i,j;
i=j=left;
int key=a[right];
int temp;
while(true)
{
if(a[j]<key)
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
i++;
}
j++;
if(j==right)
{
a[right]=a[i];
a[i]=key;
break;
}
}
return i;
}
2.双向调整
设第一个元素为主元
设置两个变量,i,j, i 指向数组左的下标,j 指向数组的右边的下标。 i和j两个变量向中间遍历
当 i 遍历到比主元大的元素i停止遍历,当 j 遍历到比主元小的元素 j 也停止遍历
当 i , j ,两个都停止遍历的时候,交换 i , j 下标所对应的元素。
交换结束之后,i++,j–,当 i > j 时,停止遍历
最后,将主元与 j 位置对应的元素进行交换。
static int partion(int a[],int left,int right)
{
//双向调整
int i,j;//两个元素
int temp;
int key=a[left];//主元
i=left+1;
j=right;
System.out.println("key:"+key+" i:"+i+" j: "+j);
while(true)
{
while(a[i]>key&&i<right)
{
System.out.println("a[i] : "+a[i]);
i++;
//System.out.println("a[i] : "+a[i]);
}
while(a[j]<key&&j>left)
{
System.out.println("a[j] : "+a[j]);
j--;
//System.out.println("a[j] : "+a[j]);
}
System.out.println("i: "+i+" j : "+j);
System.out.println("a[i]: "+a[i]+" a[j]: "+a[j]);
if(i>=j) break;
else
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
System.out.println("a[left]:"+a[left]+" a[j]: "+a[j]);
a[left]=a[j];
for (int k = 0; k < j; k++) {
System.out.print(" "+a[k]);
}
a[j]=key;
return j;
}
3.挖坑法
①.选取一个关键字(key)作为主元,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴,也是初始的坑位。
②.设置两个变量left = 0;right = N - 1;
③.从left一直向后走,直到找到一个大于key的值,然后将该数放入坑中,坑位变成了array[left]。
④.right一直向前走,直到找到一个小于key的值,然后将该数放入坑中,坑位变成了array[right]。
⑤.重复3和4的步骤,直到left和right相遇,然后将key放入最后一个坑位。
public static void main(String[] args) {
int arr[]= {4,1,3,2,2,7,6,8};
System.out.println(arr.length);
quick_sort1(arr,0,arr.length-1);
for(int i=0;i<arr.length;i++)
System.out.print(arr[i]+" ");
}
static void quick_sort1(int arr[],int left,int right)
{
if(left<right){
int i=left;
int j=right;
int temp = arr[left]; //将第一个数作为基准数存入temp中
while(i<j){
while(i<j && arr[j]>temp) //从右往左开始扫描,大于temp,j--
j--;
if(i<j){ //找到小于temp的,将它填入上一个坑中,i++
arr[i] = arr[j];
i++;
}
while(i<j && arr[i]<temp)//从右往左开始扫描,小于temp,i++
i++;
if(i<j){
arr[j] = arr[i]; 找到大于temp的,将它填入上一个坑中,j--
j--;
}
}
arr[i] = temp; //最后将temp填入最后一个坑中
quick_sort1(arr,left,i-1); //递归,完成左边的排序
quick_sort1(arr,i+1,right); //递归,完成右一半的排序
}
}