快速排序

快速排序

思想构思

分治法:比大小,再分区

1.从序列中选择一个基点元素(pivot)

默认选择索引为0的元素为基点元素

2.分区:将比基点大的数放在他的右边,比它小的放在他的左边

等于基点元素的放哪边都可以

3.对子序列1,2进行操作,直到不能再分割(子序列中只剩下一个元素)

快速排序的本质:是将每一个元素都转换成基点元素

例题:

从小到大排序

75289
left   right

步骤

  1. 先确定一个基点元素,一般以索引为0的数为基点元素(基点元素:7)

    比7小的数放在7的左边,把比7大的数放在7的右边

  2. 先定义两个索引leftright,要找出基点元素真正的索引位置,当leftright相等时就是基点元素真正的索引位置(left是索引为0的位置,right是数组索引最后的一个位置)

  3. 排序是从后面往前找,一旦找到比基数点小的数就和基点元素换位置就要和基点元素交换了位置,就要从前面向后找比基数大的数,一旦找到比基数点大的数就和基点元素换位置就要和基点元素交换了位置,交换了位置就要换方向比大小

    1. 7比9小位置不变,right--向前到7的位置

    2. 7和7比位置可以不变(也可以换位置),right--到3的位置

    3. 7和3比大互换位置

    4. 换方向进行比较,8和7比大换位置

    5. 换方向进行比较,10和7比大于7位置不变

    6. 6和7比小于7互换位置

    7. 换方向进行比较,2和7比小于7位置不变,left++

    8. left和right在6的位置上重合,那么6位置的索引就是基点元素最终的索引

数组(基点元素:7)

第一次排序

782610379
362710879

4.在基点元素左边的数都比基点元素小,在基点元素右边的数都比基点元素大

5.分成了两个子序列,用同样的方法对子序列进行排序(左边的子序列基点元素为3,右边的子序列基点元素为10)

第二次排序

362710879
236798710

6.在分子序列用同样的方法对子序列进行排序

第三次排序

236798710
236778910

代码实现

import java.util.Arrays;
public class Demo2 {
    public static void main(String[] args) {
​
        int[] arr={56, 38, 65, 97, 23, 22, 76, 23, 5, 8, 2, 78, 43, 22};
        sort(arr,0,arr.length-1);
        System.out.println("排序后:"+ Arrays.toString(arr));
    }
​
    private static void sort(int[] arr, int left, int right) {
        if(left<right){
            //基点的真实索引
            int index=getIndext(arr,left,right);
            //递归
            //左子序列
            sort(arr,left,index-1);
            //右子序列
            sort(arr,index+1,right);
​
        }
    }
​
    private static int getIndext(int[] arr, int left, int right) {
        //基点元素
        int i=arr[left];
        while (left<right){
            // 当队尾的元素大于等于基点元素时,向前挪动right指针
            while (left<right && arr[right]>=i){
                right--;
            }
            //如果队尾元素小于基点元素了,需要将其赋值给索引为left的位置
            arr[left]=arr[right];
            // 当队首元素小于等于基点元素时,向前挪动left指针
            while (left<right && arr[left]<=i){
                left++;
            }
            //如果队尾元素大于基点元素了,需要将其赋值给索引为right的位置
            arr[right]=arr[left];
        }
        // 跳出循环时left和right相等,此时的left或right就是i的正确索引位置
        arr[left]=i;
        // 返回i的正确位置
        return left;
    }
}
​

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值