算法与数据结构 快速排序算法

  1. 快速排序算法

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,比另一部分的关键字大,则可分别对这两部分记录继续进行排序,以达到整个序列有序。和冒泡算法类似,都是基于交换排序思想的,快速排序算法是对冒泡算法的改进,从而具有更高的执行效率

快速排序是通过多次比较和交换来实现排序的,其排序流程如下:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分
(2)将大于等于分界值的数据集中到数组右边,小于分界值得数据集中到数组的左边。此时,左边部分中各元素都小于等于分界值,而右边部分中各元素都大于等于分界值;
(3)左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该数据分成分成左右两部分,同样将左边放置较小值,右边放置较大值。同理,右边数据也可以进行该操作;
(4)重复以上步骤。可以看出,这是一个递归定义。通过递归将左侧的部分排好后,再递归排好右侧部分的顺序。当左右两部分数据都排好后,整个数组的排序就完成了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.执行代码演示:

    //单路快排
    public static void main(String[] args) {
        int[] a = new int[20];
        Random random = new Random();

        for (int i = 0; i < a.length;i++){
            a[i] = random.nextInt(100);
        }
        quicksort(a,0,a.length - 1);
        System.out.println(Arrays.toString(a));
    }

    private static void quicksort(int[] a, int l, int r) {
        if (l >= r) {
            return;
        }
        int p = partition(a,l,r);
        quicksort(a,l,p - 1);
        quicksort(a,p + 1,r);
    }

    private static int partition(int[] a, int l, int r) {
        int v = a[l];
        int j = l;
        for (int i = l + 1;i <= r;i++) {
           if (a[i] < v) {
               swap(a, j + 1, i);
               j++;
           }
        }
        swap(a,l,j);
        return j;
    }

    private static void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
[2, 10, 17, 22, 24, 30, 41, 42, 46, 54, 57, 69, 70, 70, 72, 79, 83, 86, 92, 95]

优化方案:
查找了下,原文链接放下边

原文链接:https://blog.csdn.net/k_koris/article/details/80585979

//双路快排
public QuickSort02(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        quickSort(0, arr.length - 1);
    }

    private void quickSort(int L, int R) {
        if (L >= R) {
            return;
        }
        //对数组进行划分 并返回划分后的中点
        int p = partition(L, R);
        quickSort(L,p - 1);
        quickSort(p + 1, R);
    }

    private int partition(int L, int R) {
        //优化一下 随机让后面的数字和第一个数字换一下
        //尽量避免极端情况(升序情况)
        swap(L, (int) (Math.random() * (R - L + 1) + L));
        int v = arr[L];
        int i = L + 1;
        int j = R;
        while (true) {
            while (i <= R && arr[i] < v) {
                i++;
            }
            while (j >= L + 1 && arr[j] > v) {
                j--;
            }
            if (i > j) {
                break;
            }
            swap(i,j);
            i++;
            j--;
        }
        swap(L,j);
        return j;
    }
//三路快排
 private void quickSort(int L, int R) {
        if (L >= R) {
            return;
        }
        swap(L, (int) (Math.random() * (R - L + 1) + L));
        int v = arr[L];
        int lt = L;
        int gt = R + 1;
        int i = L + 1;
        while (i < gt) {
            if (arr[i] < v) {
                swap(i, lt + 1);
                lt++;
                i++;
            } else if (arr[i] > v) {
                swap(i,gt - 1);
                gt--;
            } else {
                i++;
            }
        }
        swap(L,lt);
        quickSort(L,lt - 1);
        quickSort(gt, R);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值