《尚硅谷数据结构》-快速排序

目录

快速排序概念

代码实现(中值为pivot)(不推荐)

代码实现(第一个值为pivot)

代码实现(最后一个值为pivot)


快速排序概念

快速排序是对冒泡排序的一种改进。基本思想是:通过一趟排序将数据分成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

(基准值的选择有很多,比如第一个数最后一个数,或者数组的中间值)

基准值就是Pivot中心轴,建议选择第一个数为中心轴,这样编程更简单,基本思想如下

                

代码实现(中值为pivot)(不推荐)

import java.util.Arrays;

public class QuickSort {
    public static void main(String[] args) {
        int[] arr = {-9,78,0,0,23,23,-67,50};
        quickSort(arr,0, arr.length-1);
        System.out.println("arr="+ Arrays.toString(arr));
    }

    public static void quickSort(int[] arr, int left, int right){
        int l = left; //左下标
        int r = right; //右下标
        int pivot = arr[(left+right)/2]; //中值
        int temp;
        //让比pivot小的值放到左边,比pivot大的值放到右边
        while(l<r){
            // 在pivot的左边一直找,找到大于等于pivot的值才退出
            while(arr[l]<pivot){
                l += 1 ;
            }
            // 在pivot的右边一直找,找到小于等于pivot的值才退出
            while(arr[r]>pivot){
                r -= 1 ;
            }
            // l最大等于pivot的index,r最小等于pivot的index
            // 如果满足l>=r说明pivot的两边已经找完了
            if(l>=r){
                break;
            }

            // pivot两边的需要交换的值 交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            //如果交换完,发现这个arr[l] == pivot值,避免死循环
            if(arr[l] == pivot){
                r -= 1 ;
            }
            //如果交换完,发现这个arr[r] == pivot值,避免死循环
            if(arr[r] == pivot){
                l += 1 ;
            }
        }

        //避免栈溢出,如果l=r,则不会进入while循环,l和r的值就不会改变,会一直递归下去
        if(l==r){
            l += 1;
            r -= 1;
        }
        // 向左递归
        if (left<r){
            quickSort(arr, left, r);
        }
        // 向右递归
        if (right>l){
            quickSort(arr, l, right);
        }

    }
}

运行结果:

代码实现(第一个值为pivot)

public static void quickSort2(int[] arr, int left, int right){
        //判断合法性
        if (left >= right){
            return;
        }
        int l = left;
        int r = right;
        int pivot = arr[left];
        int temp;

        while(l!=r){
            //第一个数为pivot时,必须先从右开始找,否则会错
            //直到找到比pivot小的值
            while(arr[r]>=pivot && l<r){
                r--;
            }
            //直到找到比pivot大的值
            while(arr[l]<=pivot && l<r){
                l++;
            }


            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;
        }

        //当l和r相等时,就可以将pivot值拿过来放到l和r相等的地方,即中间,实现了左边都小于pivot,右边都大于pivot
        arr[left] = arr[l];
        arr[l] = pivot;

        quickSort2(arr,left,l-1);
        quickSort2(arr,r+1,right);
    }

代码实现(最后一个值为pivot)

public static void quickSort3(int[] arr, int left, int right){
        //判断合法性
        if (left >= right){
            return;
        }
        int l = left;
        int r = right;
        int pivot = arr[right];
        int temp;

        while(l!=r){
            //最后一个数为pivot,则必须先从左开始找,否则会错

            //直到找到比pivot大的值
            while(arr[l]<=pivot && l<r){
                l++;
            }
            //直到找到比pivot小的值
            while(arr[r]>=pivot && l<r){
                r--;
            }


            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;
        }

        //当l和r相等时,就可以将pivot值拿过来放到l和r相等的地方,即中间,实现了左边都小于pivot,右边都大于pivot
        arr[right] = arr[l];
        arr[l] = pivot;

        quickSort3(arr,left,l-1);
        quickSort3(arr,r+1,right);
    }

(1)选中值为pivot要考虑过多的特殊情况,所以推荐把第一个值为pivot

(2)第一个数为pivot时,必须先从右开始找,否则会错;同理,最后一个数为pivot,则必须先从左开始找,否则会错

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值