数据结构和算法(三) 快速排序-分治

介绍:

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

解析:

有数组A,取一个基准值,通过一轮排序的算法后,数组被基准值拆分为两部分,前部分小于等于基准值,后部分大于基准值。将得到前部分数组和后部分数组继续递归调用排序算法。直到排序完成。

伪代码:
排序(A, p, r) {
    if (p < r) {
	    q = 排序子方法(A, p, r)
	    排序(A, p, q-1)
	    排序(A, q+1, r)
    }
}
排序子方法(A, p, r) {
    x = A[r]
    i = p - 1
    for (j = p  to  r -1 ) {
        if (A[j] <= x) {
            i = i + 1
            A[i] 和 A[j] 交换
        }
    }
    A[i + 1] 和 A[r] 交换
    return i + 1
}
伪代码分析:

调用方法: 排序(数组A,0, 数组A.length - 1)
排序方法非常明确,p,r各表示数组的前后两端的下标。q表示拆分数组的点,根据这个点将数组拆分成两个,左边小于等于基准点,右边大于基准点。
我们重点分析排序子方法(A, p, r) 这个方法实现了排序,并返回了拆分点。
首先,我们始终取数组最后一个元素为基准点,x。
遍历数组A的除x之外的所有元素,与x进行比较。如果元素小于或等于x,i加1, 互换i和j的元素。
这里为什么是和i互换元素呢:
7, 9, 11, 3, 8
首先i初始被定义为-1,
j = 0 ; 7 <= 8 ; i = 0 ; 0和0互换,相当于没换
j = 1 ; 9 > 8 ; 不走if里面的内容,i 还是等于 0
j = 2 ; 11 > 8; 不走if里面的内容,i 还是等于 0
j = 3 ; 3 <=8 ; i = 1 ;3和1互换 数组为:7, 3, 11, 9, 8
最后,我们在循环外,还进行了一次互换,i + 1 和 r 互换,这个互换是因为,我们将r最为基准点来比较,r的位置一直是没有变化的,我们将小于r的放在左边,大于r的放在右边,最后,我们需要把r放在合适的位置,才能达到这个效果:
i = 1 ; r = 4
根据上面数组的互换,我们已经保证了 0 ~ i 的数据是比8小的,所以,我们通过 i+1和r互换,得到想要的效果。

之后就是递归调用,直到排序完成。

Java代码:
public static void main(String[] args) {
    int[] sortInt = {7, 9, 11, 3, 4, 5, 10, 8};
    quickSort(sortInt, 0, sortInt.length - 1);
}
public static void quickSort(int[] array, int start, int end) {
    if (start < end) {
        int q = partition(array, start, end);
        quickSort(array, start, q - 1);
        quickSort(array, q + 1, end);
    }
    printArray(array);
}

private static int partition(int[] array, int start, int end) {
    int x = array[end];
    int i = start - 1;
    for (int j = start; j < end; j ++) {
        if (array[j] <= x) {
            i = i + 1;
            int temp = array[i]; array[i] = array[j]; array[j] = temp;
        }
    }
    int temp = array[i + 1]; array[i + 1] = array[end]; array[end] = temp;
    return i + 1;
}

[1] 伪代码摘自 《算法导论》 机械工业出版社
[2] 介绍摘自 百度百科对于快速排序的定义 https://baike.baidu.com/item/快速排序算法/369842?fromtitle=快速排序&fromid=2084344&fr=aladdin

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值