排序算法--快速排序(简单易懂)

核心思想:将一个数组划分成两个,然后通过递归调用自身为每一个子数组进行快速排序来实现

解释原理:需要得到的数组 :小于基准值     基准值   大于基准值

输入任意一个未排序的数组,如数组arr={98,40,97,25,0,60,95,73,90,80},快速排序需要三个值,一个基准值mark(就是一个用来将数组分成两部分的值;我是选取第一个值作为基准值,即98),一个表示数组的左边起点left,一个表示右边终点right。

(1) 首先指针从右边开始探测出一个数小于基准值,arr[9]=80就小于基准值,右指针找到后探测停止,接下来左指针向右探测出一个数大于基准值的,一直探测到左右指针碰撞也没发现比基准值大的数,碰撞后左右指针,指向同一个数a[9]=80,此时将碰撞数80与基准数98交换位置,得到数组arr={80,40,97,25,0,60,95,73,90,98} ,可以发现基准数左边的数都是小于基准数的,右边没有比基准数大的数,第一次探测到碰撞后结束。

(2)此时基准值已经将数组分成两个部分(我这里右边数组为空),接下来让左边和右边数组重复(1)步骤,相当于数组

temp={80,40,97,25,0,60,95,73,90};基准值为80,左指针从80开始,右边指针从90开始,第一轮探测右指针停在73,左边指针停在97,交换位置{80,40,73,25,0,60,95,97,90},继续探测右指针停在60,左边继续探测直到与右指针在60碰撞,交换基准值80和60的位置,得到{60,40,73,25,0,80,95,97,90};可以发现基准值左边的都小于80,右边的都大于80

(3)一直重复以上步骤,直到排序完成

***********解释一下探测为什么要从右边先开始**********

如果从左边开始:

考虑极端情况数组{1,2,3,4}已经排好序了,左指针找一个比1小的数,一直找到4的位置还没找到,但此时会与右指针碰撞,将会交换位置得到{4,2,3,1},明显不对

***************以下是java代码实现快速排序***************

package Sort;

public class QuickSort {

    public static void main(String[] args) {//测试
        int arr[] = new int[10];
        for (int i = 0; i < 10; i++) {
            arr[i] = (int) (Math.random() * 99);
        }
        QuickSort quickSort = new QuickSort();
        quickSort.disPlay(arr);//原数组
        quickSort.quickSort(arr, 0, arr.length - 1);
        quickSort.disPlay(arr);//排序后数组

    }

    /**
     * @param left  起始点
     * @param right 结束点
     */
    public void quickSort(int arr[], int left, int right) {
        // i左指针   j右指针
        //mark:存基准数
        //temp是临时变量,用于交换值
        int i, j, temp, mark;
        if (left > right)
            return;
        mark = arr[left];//最左做基准数
        i = left;//左指针
        j = right;//右指针
        while (i != j) {//指针未碰撞
            //右往左找,找小于基准数的
            while (arr[j] >= mark & i < j) {//当前指针指定的数大于基准数,指针继续探测
                j--;
            }
            //从左往右找 找大于基准数的
            while (arr[i] <= mark & i < j) {//当前指针指定的数小于基准数,指针继续探测
                i++;
            }
            if (i < j) {//未发生指针碰撞
                //进行接下来代码,表示i找到了一个数大于基准数 j找到了一个小于基准值的
                //交换i、j两个数在数组中的位置
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        //一轮探测结束(指针碰撞了),将基准数与碰撞位置数交换,此时i=j
        arr[left] = arr[i];
        arr[i] = mark;

        quickSort(arr, left, i - 1);//数组左边递归
        quickSort(arr, i + 1, right);//数组右边递归
    }

    /**
     * 输出
     * @param arr
     */
    public void disPlay(int arr[]) {
        System.out.print("[");
        for (int dev : arr) {
            System.out.print(dev + " ");
        }
        System.out.print("]");
        System.out.println();
    }
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值