首页 > 其他分享 >分层,荷兰国旗,快排。

分层,荷兰国旗,快排。

时间:2022-11-12 19:34:53浏览次数:26  
标签:国旗 return int arr 快排 分层 static arr1 public

package class05;

import java.util.Arrays;

/**
 * 分层,荷兰国旗,快排。
 */
public class Code02_PartitionAndQuickSort {
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    //分层
    //小于等于区,大于区。但是每个区内部并保证有序。
    public static int partition(int[] arr, int L, int R) {
        if (L > R) {
            return -1;
        }
        if (L == R) {
            return L;
        }
        int lessEqual = L - 1;//小于区的右边界
        int index = L;//当前数
        while (index < R) {//只要当前位置,和R位置,没有撞上,就一直循环。
            //如果当前数小于等于最后一个数
            //当前数和小于区的下一个数,交换。小于区右扩,当前数跳下一个。
            //而如果当前数大于最后一个数
            //当前数,直接跳下一个。
            if (arr[index] <= arr[R]) {
                swap(arr, index, ++lessEqual);
            }
            index++;
        }
        //当前数来到R位置时,将小于区的下一个数,和R位置的数,交换。
        swap(arr, ++lessEqual, R);
        return lessEqual;//返回小于区的右边界。
        //此时整个数组arr,就分成了两层。[0, lessEqual]是小于等于arr[R]的区域。[lessEqual, R]是大于arr[R]的区域。
    }

    //荷兰国旗问题
    public static int[] netherLandFlag(int[] arr, int L, int R) {
        if (L > R) {
            return new int[]{-1, -1};
        }
        if (L == R) {
            return new int[]{L, R};
        }
        int less = L - 1;//小于区的右边界
        int more = R;//大于区的左边界
        int index = L;//当前数的位置
        while (index < more) {//这里已经不是index<R了,而是index<more。即当index撞上more时,跳出循环。
            if (arr[index] < arr[R]) {//如果当前数小于最后一个数
                swap(arr, index++, ++less);//当前数和小于区的下一个数,交换。小于区右扩,当前数跳下一个。
            } else if (arr[index] == arr[R]) {//如果当前数等于最后一个数
                index++;//当前数直接跳下一个
            } else {//如果当前数大于最后一个数
                //当前数和大于区的左边一个数,交换。大于区左扩。
                //当前位置不变,因为当前这个数是后边换过来的,还没看呢,不能直接跳下一个。
                swap(arr, index, --more);
            }
        }
        //当前数和大于区的左边界撞上时,只有最后一个数还没有归位。
        //大于区的左边界和最后一个数,交换。
        swap(arr, more, R);
        //此时三层已经分层完毕。小于arr[R]区,等于arr[R]区,大于arr[R]区。
        return new int[]{less + 1, more};//返回等于arr[R]区的,左边界和右边界的索引位置。
    }

    //快排1.0
    public static void quickSort1(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process1(arr, 0, arr.length - 1);
    }

    private static void process1(int[] arr, int L, int R) {
        if (L >= R) {
            return;
        }
        int M = partition(arr, L, R);
        process1(arr, L, M - 1);
        process1(arr, M + 1, R);
    }

    //快排2.0
    public static void quickSort2(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process2(arr, 0, arr.length - 1);
    }

    private static void process2(int[] arr, int L, int R) {
        if (L >= R) {
            return;
        }
        int[] equalArea = netherLandFlag(arr, L, R);//等于区,[equalArea[0], equalArea[1]]
        process2(arr, L, equalArea[0] - 1);
        process2(arr, equalArea[1] + 1, R);
    }

    //快排3.0
    public static void quickSort3(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process3(arr, 0, arr.length - 1);
    }

    public static void process3(int[] arr, int L, int R) {
        if (L >= R) {
            return;
        }
//        swap(arr, (int) (Math.random() * (R - L + 1)), R);
//        int[] equalArea = netherLandFlag(arr, L, (int) (Math.random() * (R - L + 1)));
        //将固定以arr[R]为比较值,换成,将随机获取一个数作为比较值。
        //这样一来,提高了效率。
        swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
        int[] equalArea = netherLandFlag(arr, L, R);
        process3(arr, L, equalArea[0] - 1);
        process3(arr, equalArea[1] + 1, R);
    }

    // for test
    public static int[] generateRandomArray(int maxSize, int maxValue) {
        int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }

    // for test
    public static int[] copyArray(int[] arr) {
        if (arr == null) {
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    // for test
    public static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
            return false;
        }
        if (arr1 == null && arr2 == null) {
            return true;
        }
        if (arr1.length != arr2.length) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        int testTime = 10;
        int maxSize = 20;
        int maxValue = 100;
        boolean flag = true;
        System.out.println("test start!");
        for (int i = 0; i < testTime; i++) {
            int[] arr0 = generateRandomArray(maxSize, maxValue);
            int[] arr1 = copyArray(arr0);
            int[] arr2 = copyArray(arr0);
            int[] arr3 = copyArray(arr0);
            int[] arr4 = copyArray(arr0);
            Arrays.sort(arr4);
            quickSort1(arr1);
            quickSort2(arr2);
            quickSort3(arr3);
            if (!isEqual(arr1, arr2) || !isEqual(arr1, arr3) || !isEqual(arr1, arr4)) {
                flag = false;
                break;
            }
        }
        System.out.println("test start!");
        System.out.println(flag ? "nice!" : "oops!");
    }
}

 

标签:国旗,return,int,arr,快排,分层,static,arr1,public
From: https://www.cnblogs.com/TheFloorIsNotTooHot/p/16884474.html

相关文章

  • 计算机网络的分层体系结构
    计算机网络的分层体系结构点击查看代码物理层:物理接口规范,传输比特流,网卡是工作在物理层的.数据链路层:成帧,保证帧的无误传输,MAC地址,形成EHTHERNET帧数据链......
  • 分层协议
    分层协议为什么要分层?将庞大问题化为很多小问题,逐个击破。发送文件前要完成的工作:(1)发起通信的计算机必须将数据通信的通路进行激活。(2)要告诉网络如何识别目的主机......
  • 网络分层
    基本概念1.上层依赖下层2.每个层次都有自己的职责,为了完成这些职责需要准守一些基本的规则,这个规则就是协议。   实体层/物理层通过无线电波、电缆等方式把各......
  • 数仓分层设计
    概述数仓分层是数据仓库设计中十分重要的一个环节,优秀的分层设计能够让整个数据体系更容易理解和使用 数据分层的作用我们需要一套行之有效......
  • CS Academy Telegraph 题解 (分层DP)
    CSAcademy是一个比较小众的罗马尼亚OJ,UI好看功能多样,但是需要fq才能注册。访问是不用fq的常用工具:画图找不同题目链接前段时间刚做过类似的分层dp题,这次又忘了,深刻反......
  • HCIA--网络协议介绍及OSI参考模型分层
    不同的协议栈用于定义和管理不同网络的数据转发规则。数据通信协议的定义:决定数据的格式和传输的一组规则或者一组惯例。分层模型的作用:OSI七层参考模型:下层为上层提供服务,......
  • [单片机框架] 框架文件分层介绍
    什么是框架?程序框架其实就类似一个文件大纲或者模板。因为写程序就和类似于写文章,如果没有大纲或者模板那么你写起来就会比较费劲。一个好的框架,能事半功倍,节约时间,减少错误......
  • 为什么要数据仓库分层?好处是?
    按照数据流入流出的过程,数据仓库架构可分为三层——源数据、数据仓库、数据应用。 源数据层(ODS):此层数据无任何更改,直接沿用外围系统数据结构和数据,不对外开放;为临时存储层,......
  • 【XSY3892】【hihocoder1147】时空阵(分层图dp)
    设\(dp(i,t,l)\)表示已经定好前\(i\)层,共有\(t\)个节点,其中第\(i\)层有\(l\)个节点。直接转移即可,注意一些细节:第\(1\)层只有\(1\)号节点。同层之间......
  • 快排与冒泡
    快排的实现原理:选取一个基点(列表第一个元素),然后从右往左对比,比这个基点小的数字放在left列表中,比基点大的数字放在right列表中这样left所有元素肯定是小于right的......