Java排序算法:快速排序

Java快速排序


原理:
在待排序数组中选定一个分界值(取第一个),基于分界值将数组切分成两部分。将数组中大于分界值的元素全部放到右边,小于分界值的元素全部放到左边,这样左边所有的元素都小于右边的元素。
对左右两边的元素进行排序,一样的,在左边的部分中选取一个分界值(取第一个),基于该分界值继续将左边部分的所有元素切分成两部分。第一次切分得到的右边部分同样进行切分操作。
递归执行以上的操作直到不需要切分为止,经过以上的操作,最后的数组就是排好序的了。

切分的具体实现逻辑:
1、找一个分界值(取第一个),用两个指针分别指向数组的头部和数组尾部的下一位,这里称为左指针、右指针;
2、先从右指针开始向左遍历,当遍历到当前值小于分界值时就停下来 ,同时记录指针的位置;
3、从左指针开始向右遍历,当遍历到当前值大于分界值时就停下来,同时记录指针的位置;
4、交换当前左右指针所在的元素;
5、重复执行2、3、4的操作,直到左指针的值大于或等于右指针的值就停下来。

举例:
在这里插入图片描述
代码实现:

package com.example.algorithmdemo.sortingAlgorithm;

/**
 * 快速排序算法
 */
public class Quick {

    /**
     * 调用该方法开始排序
     */
    public static void sort(Comparable[] a){
        int low = 0;
        int high = a.length-1;
        sort(a,low,high);
    }

    /**
     * 对数组a中下标为low到high的元素进行排序
     * @param a
     * @param low
     * @param high
     */
    public static void sort(Comparable[] a,int low,int high){
        if(low >= high){
            return;
        }
        //对数组进行切分,得到分界值的下标
        int partition = partition(a, low, high);
        //对左边部分进行排序
        sort(a,low,partition-1);
        //对右边部分进行排序
        sort(a,partition+1,high);
    }

    /**
     * 对数组a中下标为low到high的元素进行划分,分成两组
     * @param a
     * @param low
     * @param high
     * @return int 返回分界值的下标
     */
    public static int partition(Comparable[] a,int low,int high){
        Comparable key = a[low];//初始分界值取数组第一个
        int left = low;//左指针指向头部
        int right = high + 1;//右指针指向尾部的下一个位置
        //开始切分
        while (true){
            //从右指针开始往左遍历,直到找到一个比分界值小的元素就停止,此时right为该元素的下标
            while (less(key,a[--right])){
                //如果左右指针相等了就停止
                if(left == right){
                    break;
                }
            }
            //从左指针开始往右遍历,直到找到一个比分界值大的元素就停止,此时left为该元素的下标
            while (less(a[++left],key)){
                if(left == right){
                    break;
                }
            }

            //如果左指针大于或等于右指针就停止
            if(left >= right){
                break;
            }else{
                //交换下标为left和right的值
                exchange(a,left,right);
            }
        }
        //交换分界值与right/left处的值
        exchange(a,low,right);
        //返回分界值的位置
        return right;
    }

    /**
     * 数组元素i和j交换位置
     * @param a
     * @param i
     * @param j
     */
    private static void exchange(Comparable[] a,int i,int j){
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    /**
     * 判断参数a是否小于参数b
     * 是则返回true
     * @param a
     * @param b
     * @return
     */
    private static boolean less(Comparable a,Comparable b){
        return a.compareTo(b) < 0;
    }
}

测试:

package com.example.algorithmdemo.test;

import com.example.algorithmdemo.sortingAlgorithm.Quick;

import java.util.Arrays;

public class QuickTest {
    public static void main(String[] args) {
        Integer[] a = {6, 1, 2, 7, 9, 3, 4, 5, 8};
        Quick.sort(a);
        System.out.println(Arrays.toString(a));
    }
}

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值