用java实现快速排序算法

第一种方法:(从数组右边开始)

1.选择一个比较值c,以数组的第一个为例。
2.从右边开始查找比c小的值,再从左边开始查找比c大的值,进行互换。
3.当左边和右边同时指向一个值v(比c小,因为是从右边开始递减的),会退出当前循环。
4.交换c和v的值,返回v所在的地址。
5.递归,以此类推


public class QuickSort {
    public static int[] quickSort(int[] a,int first,int last){
        if(first<last){                //至少两个位置
        int pivotIndex=partition(a,first,last);  //定义pivotIndex中间位置。partition是检索这个方法
        quickSort(a,first,pivotIndex-1);              //排序左半边
        quickSort(a,pivotIndex+1,last);               //排序右半边
        }
        return a;
    }
    public static  int partition(int[] a,int left,int right){//对数组A下标从first到last中选一个主元,确定其位置,左边小于,右边大于。

        int pivot=a[left];//先定义区间数组第一个元素为主元
        int i=left;   //定义最低的索引low是first+1。比主元大一位
        int j=right;     //定义最高的索引high是last
        while(i!=j){   //当low小于high的位置时,执行以下循环
        	while(a[j]>pivot&&i<j){//当high的索引上的值比主元大时,且索引大于low时
                j--;                      //寻找比主元小的值的位置索引
            }
            while(a[i]<=pivot&&i<j){//当low的索引上的值比主元小时,索引小于high时
                i++;                       //寻找比主元大的值的位置索引。
            }
            
            if(i<j){   //交换low和high的值
                int t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
       }
       
           a[left]=a[j];
           a[j]=pivot;
           return j;
    }
		public static void main(String[] args) {
			int[]a=new int[]{50,10,90,30,70,40,80,60,20};
			int [] k=quickSort(a,0,a.length-1);
			for(int i=0;i<k.length;i++){
				System.out.print(k[i]+" ");
			}
		}
}

第二种方法:(从数组左边开始数)

public static  int partition(int[] a,int left,int right){//对数组A下标从first到last中选一个主元,确定其位置,左边小于,右边大于。
        int pivot=a[right];//先定义区间数组第一个元素为主元
        int i=left;   //定义最低的索引low是first+1。比主元大一位
        int j=right;     //定义最高的索引high是last
        while(i!=j){   //当low小于high的位置时,执行以下循环
        	while(a[i]<=pivot&&i<j){//当low的索引上的值比主元小时,索引小于high时
                i++;                       //寻找比主元大的值的位置索引。
            }
        	while(a[j]>=pivot&&i<j){//当high的索引上的值比主元大时,且索引大于low时
                j--;                      //寻找比主元小的值的位置索引
            }
            if(i<j){   //交换low和high的值
                int t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
       }
       
           a[right]=a[i];
           a[i]=pivot;
           return i;
    }

有同学可能就要问了,为什么第一种方法数组一定要从右边开始呢。
while(arr[j]>=temp&&i<j){
j–;
}
while(arr[i]<=temp&&i<j){
i++;
}
这里两个while的顺序是不能改变的,想一想:
假设对如下进行排序:
在这里插入图片描述
如上图,6在左,9在右 我们将6作为基数。
假设从左边开始(与正确程序正好相反)
于是i 就会移动到现在的 数字 7 那个位置停下来,而 j 原来在 数字 9 那个位置 ,因为
while(arr[j]>=temp&&i<j)
于是,j 也会停留在数字7 那个位置,于是问题来了。当你最后交换基数6与7时,不对呀!!。
问题在于当我们先从在边开始时,那么 i 所停留的那个位置肯定是大于基数6的,而在上述例子中,为了满足 i<j 于是 j也停留在7的位置
但最后交换回去的时候,7就到了左边,不行,因为我们原本 交换后数字6在边应该是全部小于6,右边全部大于6.但现在不行了。
于是,我们必须从右边开始,也就是从基数的对面开始。
第三种方法:(基于第一种,从左边开始数的修正算法)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值