快速排序算法

14 篇文章 0 订阅

原理:

快速排序的本质就是把基准数大的都放在基准数的右边, 把比基准数小的放在基准数的左边,这样就找到了该数据在数组中的正确位置

时间复杂度:


最好的情况是O(N*logN)
最坏的情况是O(N2),最左边或者最右边是边缘的数,即最大(1,2,3,4,5)或者最小(5,4,3,2,1)的, 因为每次分成两个区间时,只能确定一个数的位置


避免出现O(N2)

为了避免已经排好序的这种情况,可以随机取一个位置的数与数组最后一个数做交换在来排序

下面是选取左边的数为基准数排序,然后递归


package leetcode.editor.cn;

import java.util.Arrays;

/**
 * @description: 快速排序:
 * 1.会先把数组中一个数当做基准数,一般把数组中最左边的数当做基准数,然后两边进行检索。
 * 2.先从右边(j)检索比基准数小的,检索到了停下来,
 * 3.再从左边(i)检索比基准数大的,检索到了停下来,
 * 4.然后交换刚刚两个位置(j和i)的元素,
 * 5.然后继续检索,如果i和j相遇了,把基准数放到i位置上面,基准数前面的数组都比它小,后面的数组都比它大,第一轮排序完成
 * 6.在排基准数左的数组和右边的数组
 *
 * 时间复杂度:每一层的比较与交换是O(n),一共能分O(logN),时间复杂度为O(N*logN)
 * 最坏的情况是已经排好序了,时间复杂度为O(N2),解决办法:可以随机取一个位置的数与数组最后一个数做交换在来排序
 * 空间复杂读:logN
 * @author: xt
 * @create: 2022-04-03 23:47
 **/
public class QuickSort2 {

    public static void main(String[] args) {
        int[] arr = {10,6, 8, 7, 4, 2, 6, 9, 3, 5};
        sort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    static void  sort(int[] arr, int left,int right){
        //进行判断,左边的数组范围要小于右边
        if(left>right){
            return;
        }
        //定义基准数,默认以左边的数
        int tmp=arr[left];
        //i指向这个范围数组的最左边
        int i=left;
        //j指向这个范围数组的最右边
        int j=right;
        //当i和j不相遇的时候,进行检索
        while(i!=j){

            //因为是以左边为基准,所以先移动右边
            //先从右往左检索,如果检索到比基准数小的,就停下,
            // 如果检索到比基准数大或者等于的,就一直往右移动
            //但 i不能大于j,如果大于
            while(i<j && arr[j]>=tmp){
                j--;
            }
            //先从左往右检索,如果检索到比基准数大的,就停下,
            // 如果检索到比基准数小或者等于的,就一直往左移动
            while(i<j && arr[i]<=tmp){
                i++;
            }

            //i和j都停下了,交换对应的元素
            swap(arr,i,j);
        }
        //但i和j相遇了,就交换基准数和相遇位置的元素
        arr[left]=arr[i];
        arr[i]=tmp;
        //对基准数前面的元素进行排序
        sort(arr, left,i-1);
        //对基准数后面的元素进行排序
        sort(arr, j+1,right);
    }

    static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}


下面是选取右边的数,分治的思想

import java.util.Arrays;

/**
 * @description: 快速排序
 * @author: xt
 * @create: 2021-04-04 20:05
 **/
public class QuickSort {

    public static void main(String[] args) {
        int[] arr={1, 8, 7, 4, 2, 6, 9, 3, 5};
        sort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    static void sort(int[] arr ,int leftBound ,int rightBound){
       if(rightBound<=leftBound){
           return;
       }
       int mid=partition(arr,leftBound,rightBound);
       sort(arr,leftBound,mid-1);
       sort(arr,mid+1,rightBound);
    };

    static int partition(int[] arr ,int leftBound ,int rightBound){
        int pivot=arr[rightBound];
        int right=rightBound-1;
        int left=leftBound;
        while(left<=right){
            //为了防止最右边的数据是最大,一直加超过数组长度报错,加上left<=right
            while (left<=right&&arr[left]<=pivot){
                left++;
            };
            //为了防止最右边的数据是最小,一直减为-1报错,加上left<=right
            while (left<=right&&arr[right]>=pivot){
                right--;
            }
            if(left<right){
                //左右指针还没有重合,把比基准数大的值,与比基准数小的值换个位置
                //[1, 3, 7, 4, 2, 6, 9, 8, 5]
                //[1, 3, 2, 4, 7, 6, 9, 8, 5]
                swap(arr,left,right);

            }
        }
       //经过一次比较,把基准数的left上,这样基准数右边的都是比基准数小的,左边都是大的
        swap(arr,left,rightBound);
        //第一次交换后,可以确定5的位置
        //[1, 3, 2, 4, 5, 6, 9, 8, 7]
       return left;
    };
    static void swap(int[] arr ,int i,int j){
        int tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值