算法day3 快速排序详解与荷兰国旗问题

1.荷兰国旗问题

        荷兰国旗问题,也就是快速排序中需要用到的partition过程,问题描述:给定一个数组和一个数Num,要求对数组一番操作后,等于Num的数全放在中间,小于Num的数全放在左边,大于Num的数全放在右边,也就是将数组分为小于,等于,大于Num的三个区域,在这些区域内部是不要求有序的。 * 解法思路: 三指针操作,左指针less初始指向-1位置,右指针more初始指向数组最后一个元素,指针L=数组第一个元素,划分值Num为数组最后一个数,开始遍历数组,做如下操作:

当前数arr[L]<划分值arr[R],交换当前数和小于区域的下一个arr[++less],L往后移动,L++

当前数arr[L]>划分值arr[R],交换当前值和大于区域的前一个arr[--more],L此时保持不动,因为由后面换到前面去的数要再次比较大小

当前数arr[L]=划分值arr[R],L直接往后移动,L++

上述判断一直持续到L指正进入了大于区域,也就是L>=more时结束,最后由于大于区域的最后一个划分元素Num,也就是arr[R],始终未动,我们需要将这个数移动到中间来,那么交换一下arr[more]和arr[R]即可,至此,荷兰国旗问题解决,那么快速排序就是在荷兰国旗的问题上对左边小于区域和右边大于区域重复上述所有过程,也就是跑递归,就可以使得整个数组一定能达到有序状态

2.快速排序

        快速排序,时间复杂度最差O(N^2),但由于借助随机选取了划分值,破环了该随机性,每一个元素被选中为划分值的概率是随机的,因此需要对N种情况求数学期望,最终得出快排的时间复杂度是O(N*logN),空间复杂度为logN (与划分值的选取有关系,这里也是一个数学期望的结论)

源码如下:

public class QuickSort {
    public static void quickSort(int[] arr) {
        if (arr == null || arr.length < 2)
            return;
        quickSort(arr, 0, arr.length - 1);
    }

    public static void quickSort(int[] arr, int L, int R) {
        if (L < R) {
            Utils.swapPuTong(arr, L + (int) (Math.random() * (R - L + 1)), R);       //随机选一个位置与最右侧的位置做交换,然后以最右侧位置的数做partition
            int[] p = partition(arr, L, R);
            quickSort(arr, L, p[0] - 1);      //小于区
            quickSort(arr, p[1] + 1, R);      //大于区
        }
    }

    /**
     * 处理arr[l...r]的函数,类似荷兰国旗问题
     *
     * @param arr 数组
     * @param L   左边界
     * @param R   右边界
     * @return 返回一个等于区域(左边界,右边界),也就是一个长度为2的数组res,res[0],res[1]
     */
    public static int[] partition(int[] arr, int L, int R) {
        int less = L - 1;     //<区右边界
        int more = R;         //>区左边界
        while (L < more) {          //L表示当前数的位置,arr[R]就是划分值
            if (arr[L] < arr[R])         //当前数小于划分值
                Utils.swapPuTong(arr, ++less, L++);
            else if (arr[L] > arr[R])
                Utils.swapPuTong(arr, --more, L);   //当前数大于划分值
            else
                L++;
        }
        Utils.swapPuTong(arr,more,R);
        return new int[]{less+1,more};
    }


    public static void main(String[] args) {
        int[] arr = Utils.getArray(10,0,100);
        System.out.println(Arrays.toString(arr));
        quickSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
荷兰国旗问题是一个经典的排序问题,它要求按照荷兰国旗的颜色顺序(红、白、蓝)对一个包含红、白、蓝三种颜色的数组进行排序快速排序算法可以用来解决荷兰国旗问题。该算法基于分治的思想,通过多次划分和交换元素来达到排序的目的。以下是快速排序算法解决荷兰国旗问题的步骤: 1. 选择一个枢轴元素(一般是数组的最后一个元素)。 2. 初始化三个指针:low指向数组的起始位置,high指向数组的末尾位置,mid指向数组的起始位置。 3. 从头遍历数组,如果当前元素小于枢轴元素,则交换当前元素和mid指针指向的元素,并将mid指针后移一位。 4. 如果当前元素等于枢轴元素,则将high指针前移一位。 5. 如果当前元素大于枢轴元素,则交换当前元素和high指针指向的元素,并将high指针前移一位。 6. 重复步骤3到步骤5,直到low指针和high指针相遇为止。 7. 最后,将枢轴元素放在mid指针的位置上,这样数组就被分成了三个部分:小于枢轴元素的部分、等于枢轴元素的部分和大于枢轴元素的部分。 8. 递归地对小于和大于枢轴元素的部分进行排序。 以下是一个示例荷兰国旗问题快速排序的实现(使用Python语言): ```python def dutch_flag_sort(arr): def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i] def quicksort(arr, low, high): if low < high: pivot = arr[high] mid = low for i in range(low, high): if arr[i] < pivot: swap(arr, i, mid) mid += 1 swap(arr, mid, high) quicksort(arr, low, mid - 1) quicksort(arr, mid + 1, high) quicksort(arr, 0, len(arr) - 1) return arr # 示例用法 arr = [2, 0, 2, 1, 1, 0] sorted_arr = dutch_flag_sort(arr) print(sorted_arr) ``` 上述示例代码会输出 `[0, 0, 1, 1, 2, 2]`,即按照荷兰国旗顺序排序的结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值