快速排序(简单易懂)

假设我们想对十个随机大小的数进行从小到大的排序, 例如5,8,4,6,7,9,2,10,1,3; 可以运用比较简单的冒泡排序,从左到右依次进行比较,进行几次循环就可以排出来,虽然比较简单,但是速度却比较慢, 为什么说他慢呢?自然是有比他更快的方法,也就是神奇的快速排序,一种听名字就很快的排序方法
5,8,4,6,7,9,2,10,1,3
原理其实比较简单:首先找到一个数字作为比较的标准(KEY),通常KEY选取最外侧的数字,我将最左边的数字5作为KEY,还需要两个移动的指针(L)和(R)
然后将L和R分别指向数字的两端L(5),R(3),先比较R(3)与KEY(5)的大小,如果R<KEY,指针R停止移动,比较L(5)与KEY(5)的大小,如果L>KEY,指针L停止移动,此时L(5)不大于KEY(5),L指针继续向右移动,指向数字8,比较L(8)与KEY(5)的大小,L>KEY,指针L停止移动,R(3)与L(8)指针指向的数字交换位置,第一次交换得到的数字排序就是:
5,3,4,6,7,9,2,10,1,8
交换之后指针R(8)继续移动,指向数字1,指针R(1)停止移动,指针L(3)向右移动,指向数字4,指针L(4)继续向右移动指向数字6,指针L(6)停止移动,R(1)与L(6)指针指向的数字交换位置,第二次交换得到的数字排序就是:
5,3,4,1,7,9,2,10,6,8
交换之后指针R(6)继续移动,指向数字10,指针R(10)继续向左移动指向数字2,指针R(2)停止移动,指针L(1)向右移动,指向数字7,指针L(7)停止移动,R(2)与L(10)指针指向的数字交换位置,第二次交换得到的数字排序就是:
5,3,4,1,2,9,7,10,6,8
交换之后指针R(7)继续移动,指向数字9,指针R(9)继续向左移动指向数字2,此时指针R与指针L相遇,同时指向数字2,指针L(2)与指针R(2)停止移动,将指针所指数字与KEY做交换,此时得到数字排序如下:
2,3,4,1,5,9,7,10,6,8
此时可以很明显的看出,5(KEY)左边的数字都比5小,右边的数字都比5大,第一步完成,然后就是将5左边和右边分成两组数组,再进行取上述循环,如将左边的数列,数字2取作KEY,将指针L与R分别指向3和1,先比较R(1)与KEY(2)的大小,如果R<KEY,指针R停止移动,比较L(2)与KEY(2)的大小,此时L(2)不大于KEY(2),L指针继续向右移动,指向数字3,L>KEY,指针L停止移动,R(1)与L(3)指针指向的数字交换位置,交换后得到的数字排序就是:
2,1,4,3,5,9,7,10,6,8
交换之后指针R(3)继续移动,指向数字4,指针R(4)继续向左移动指向数字1,此时指针R与指针L相遇,同时指向数字1,指针L(1)与指针R(1)停止移动,将指针所指数字与KEY做交换,此时得到数字排序如下:
1,2,4,3,5,9,7,10,6,8
此时可以看出,2(KEY)左边的数字都比2小,并且已经完成排序,右边的数字都比2大,第二步完成,再将数字2右边的数列,数字4取作KEY,将指针L与R分别指向4和3,先比较R(3)与KEY(4)的大小,如果R<KEY,指针R停止移动,比较L(4)与KEY(4)的大小,此时L(4)不大于KEY(4),L指针继续向右移动,指向数字3,此时指针R与指针L相遇,同时指向数字3,指针L(3)与指针R(3)停止移动,将指针所指数字与KEY做交换,此时得到数字排序如下:
1,2,3,4,5,9,7,10,6,8
此时5左边已经完成排序,右边同左边操作就可以完成。

	将上述过程转换为JAVA代码如下:
public class QuickSort {
    public static void main(String[] args) {
        int[] arr = { 5,8,4,6,7,9,2,10,1,3 };
        quickSort(arr, 0, arr.length - 1);
        System.out.println("排序后:");
        for (int i : arr) {
            System.out.println(i);
        }
    }

    private static void quickSort(int[] arr, int lL, int R) {

        if (L< R) {
            // 找寻基准数据的正确索引
            int index = getIndex(arr, L, R);

            // 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
            quickSort(arr, 0, index - 1);
            quickSort(arr, index + 1, high);
        }

    }

    private static int getIndex(int[] arr, int L, int H) {
        // 基准数据
        int KEY = arr[L];
        while (L < R) {
            // 当队尾的元素大于等于基准数据时,向左挪动R指针
            while (L < R && arr[R] >= tmp) {
               R--;
            }
            // 如果队尾元素小于tmp了,需要将其赋值给low
            arr[L] = arr[R];
            // 当队首元素小于等于tmp时,向前挪动low指针
            while (L< R && arr[L] <= tmp) {
                L++;
            }
            // 当队首元素大于tmp时,需要将其赋值给R
            arr[R] = arr[L];

        }
        // 跳出循环时L和R相等,此时的L或R就是tmp的正确索引位置
        // 由原理部分可以很清楚的知道L位置的值并不是tmp,所以需要将tmp赋值给arr[L]
        arr[L] = tmp;
        return L; // 返回tmp的正确位置
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值