数据结构与算法之快速排序

/*
 * 快速排序
 * 快速排序是基于划分的思想,就是将一个数组一分为2的目的来进行递归排序的。
 * 首先快速排序会选取一个基数,也就是比较的枢纽,一般选取数组的第一个或者最后一个数作为基数,这里我们以取第一个元素为例进行分析
 * 比如存在一个数组int a =  {7,3,5,2,9,8,6,1,4,7};
 * 首先取出index为0的元素7,然后定义两个游标i = 1, j = a.length -1 = 9;
 * 先拿7和a[j](7)比较,7不大于a[j](7),那么j就往左移动一位(j--),此时j=8,然后再拿7和a[j-1](4比较),7比4大,j值不变
 * 接下来再比较a[i](3),7比3大,i右移一位(i++),此时i=2,然后比较7和a[i](7), 7比5大,i继续右移一位,此时i=3,
 * 再比较7和a[i](2),7比a[i](2)大,此时i继续右移(i++),此时i=4, 比较7和a[i](9),7小于a[i],
 * 再拿i和j比较,此时i小于j,那么a[i]和a[j]交换位置。此时的数组a为[7,3,5,2,4,8,6,1,9,7]
 * 然后j继续左移一位(j--),此时j=7,比较7和a[j](1),7比a[j]大,j值不变
 * 接下来i右移一位(i++),此时i=5,比较7和a[i](8),a[i](7)要大于7,比较i和j
 * 此时i<j, a[i]和a[j]进行交换。此时数组a为[7,3,5,2,4,1,6,8,9,7]
 * 然后j--,此时j=6,a[j] = 6小于7,j值不变;i++,此时i = 6,a[i](6)小于7,i++,此时a[7](8)大于7,i不变。比较i和j
 * 此时i>j,此时将基数与a[j]交换,第一趟排序结束,等到的数组a为[6,3,5,2,4,1,7,8,9,7],基数索引为j=6,
 * 然后使用划分,将数组a从逻辑上划分为a[0-5],a[7-9]然后两个数组一次进行上述的排序(递归),从而得到最终的排序数组a
 * 代码示例如下:
 */
public class QuickSort {

    public static void main(String[] args) {
        int[] a = {7,3,5,2,9,8,6,1,4,7};
        quickSort(a, 0, a.length -1);
        System.out.println(Arrays.toString(a));
    }
    
    private static void quickSort(int[] a, int left, int right){
        //取出基数,这里是取的数组的第一个元素
        int temp = a[left];
        //游标i从基数之后的第一位取起
        int i = left +1;
        //游标j从数组的最后一位取起
        int j = right;
        //如果i<j表示排序还没有完成,继续执行
        while(i < j){
            //从右向左取元素,取出第一个比基数小的元素的索引位置
            while(i<=j && temp <= a[j]){
                j--;
            }
            //从左向右取元素,取出第一个比基数大的元素的索引位置
            while(i<=j && temp > a[i]){
                i++;
            }
            //如果i>=j表示所有的元素都比较过了,一趟遍历结束
            if(i>=j){
                break;
            }else{
                //如果i<j表示还有元素没有比较到,此时的a[i]大于基数,a[j]小于基数,此时需要交换a[i]与a[j]的元素值
                int tempi = a[i];
                a[i] = a[j];
                a[j] = tempi;
            }
        }
        //第一趟排序借宿的时候需要把基数和a[j]的元素交换一下
        a[left] = a[j];
        a[j] = temp;
        System.out.println(Arrays.toString(a));
        //判断基数元素的左边是否只有一个元素了,
        //如果只有一个元素,则不需要排序了
        //否则要划分出左边的数组,进行快排
        if(left < j-1){
            quickSort(a, left, j-1);
        }
        //判断基数元素的右边是否只有一个元素了,
        //如果只有一个元素,则不需要排序了
        //否则要划分出右边的数组,进行快排
        if(j+1 < right){
            quickSort(a, j+1, right);
        }
    }

}

//执行结果如下:

[6, 3, 5, 2, 4, 1, 7, 8, 9, 7]
[1, 3, 5, 2, 4, 6, 7, 8, 9, 7]
[1, 3, 5, 2, 4, 6, 7, 8, 9, 7]
[1, 2, 3, 5, 4, 6, 7, 8, 9, 7]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 7]
[1, 2, 3, 4, 5, 6, 7, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 7, 8, 9]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值