zoukankan      html  css  js  c++  java
  • 【Java数组算法17】

    一、冒泡排序:找到最大数,然后摘出来,在找出第二大数摘出来,依次进行

    举例了解原理:

    int[] data = {3,1,6,2,5}

    比较之前的数据:3,1,6,2,5     (比较的时候都是按照第一个数和第二个数进行比较,如果第一个数大于第二个数调换顺序、否则保持不变,第二个数和第三个数进行比较,依次类推)

    第一轮:

    1,3,6,2,5(第1个数和第2个数比较的结果)

    1,3,6,2,5(第2个数和第3个数比较的结果)

    1,3,2,6,5(第3个数和第4个数比较的结果)

    1,3,2,5,6(第4个数和第5个数比较的结果)

    比较完第1轮以后把最大的一个数(6)摘出来,进行第2轮的比较

    第二轮原数据:1,3,2,5

    第二轮:

    1,3,2,5

    1,2,3,5

    1,2,3,5

    比较完第2轮以后把最大的一个数(5)摘出来,进行第3轮的比较

    第三轮原数据:1,3,2

    第三轮:

    1,3,2

    1,2,3

    比较完第3轮以后把最大的一个数(3)摘出来,进行第4轮的比较

    第四轮原数据:1,2

    第4轮:

    1,2

    通过上面的比较可以清楚的知道:data数组内有5个数,对比了4轮,10次

    由此可以得出一个公式:轮数:5-1;次数:5*(5-1)/2=10。如果数组内有n个数,那么比较的轮数为:n-1,每一轮进行的次数:n-1-1,总共次数:n*(n-1)/2

    所以冒泡排序有两个动作:进行了几轮,进行了几次

    在程序上解决方法:

    1、双层for循环,外层for循环控制轮数,内层for循环控制次数。

    2、内层for语句通过if判断来进行具体的转换:

    AB进行转换,先把A赋值给C,然后把B赋值给A,最后把C赋值给B

    3、遍历数组,输出转换后的结果

    package com.JavaStudy.studyArray0604;
    
    /**
     * @Author wufq
     * @Date 2020/6/4 15:00
     * 冒泡排序
     */
    public class BubbleShort01 {
        public static void main(String[] args){
            int[] data = {3,1,6,5,2};
    
            //双层for循环来进行排序
            for(int i=data.length-1;i>0;i--){ 
    
                for(int j =0;j<i;j++){
    
                    if(data[j]>data[j+1]){
                        int temp = data[j];
                        data[j]= data[j+1];
                        data[j+1]=temp;
                    }
                }
            }
            //遍历数组,输出结果
            for(int i=0;i<data.length;i++){
                System.out.print(data[i]+" ");
            }
        }
    }
    package com.JavaStudy.studyArray0604;
    
    /**
     * @Author wufq
     * @Date 2020/6/4 16:29
     */
    public class Data {
        public static void main(String[] args){
            int[] data = {3,1,6,5,2,7};
    
            //双层for循环来进行排序
            for(int i=1;i<=data.length-1;i++){
    
                for(int j =0;j<data.length-1;j++){
    
                    if(data[j]>data[j+1]){
                        int temp = data[j];
                        data[j]= data[j+1];
                        data[j+1]=temp;
                    }
                }
            }
            //遍历数组,输出结果
            for(int i=0;i<data.length;i++){
                System.out.print(data[i]+" ");
            }
        }
    }

    以上两段代码的结果是一样的,区别在于两层for循环,第一种的外层for循环是按照先第4轮-->第1轮,而内层for循环是在小于外层for循环数的基础上进行的次数的计算;第二种的外层for循环是按照先第1轮-->第4轮,而内层for循环是在小于数组长度-1(即:数组下标)的基础上进行次数的计算。所以不管按照那种方式原理都是一样的,即:外层循环控制轮数,内层循环控制次数。但是第二种计算的次数明显多于第一种,所以还是建议采用第一种方式进行排序

    二、选择排序

    原理:找出最小数然后与数组的第一个元素进行对比然后互换。所以内层for循环分两步:1、找到最小数的下标,2、最小数的下标与第一个元素的下标进行对比然后互换

    举例了解原理:

    int[] arr={3,1,5,7,4}

    比较之前的数据:3,1,5,7,4    (第一轮把第一个数赋值给最小数,然后最小数依次进行比较,找到最小数取出来,第二轮把第二个数当做最小数,然后进行比较,找出第二个最小数,依次寻找。。。)

    第一轮:

    原数:3,1,5,7,4

    对比后:1,3,5,7,4

    第二轮:

    原数:3,5,7,4

    对比后:3,5,7,4

    第三轮:

    原数:5,7,4

    对比后:4,7,5

    第四轮:

    原数:7,5

    对比后:5,7

    通过上面的比较可以清楚的知道:选择排序也是先确定几轮,然后每一轮找到最小数,并摘出来。

    package com.JavaStudy.studyArray0604;
    
    /**
     * @Author wufq
     * @Date 2020/6/4 17:02
     * 选择排序:找到最小数然后和数组的第一个元素进行对比
     */
    public class SelectShort01 {
        public static void main(String[] args){
            int[]  arr={2,1,7,5,3,8};
    
            for(int i=0;i<arr.length-1;i++){
    
                //第一次循环都是和arr[i]元素交换位置,将剩余数据中的第一个元素看做最小元素
                int min = i;
    
                //这个循环负责找出最小元素的下标
                for(int j = i+1;j<arr.length;j++){
                    if(arr[min]>arr[j]){
                        min = j;
                    }
                }
    
                //一定要找出最小元素的下标
                //arr[min]和arr[i]交换位置
                if(min!=i){
                    int temp = arr[min];
                    arr[min] = arr[i];
                    arr[i]=temp;
                }
            }
    
            for(int i=0;i<arr.length;i++){
                System.out.print(arr[i]+"	");
            }
        }
    }

    不管是冒泡排序还是选择排序,次数都是在轮的基础上进行的调换,所以内层循环时j都要在i控制的轮次里面进行次数的调换

    如:冒泡排序:

    for(int i=data.length-1;i>0;i--){ 
      for(int j =0;j<i;j++){

    选择排序:

    for(int i=0;i<arr.length-1;i++){
    
                for(int j = i+1;j<arr.length;j++){
     

     三、二分法根据下标查找数据元素

    使用二分法查找算法在数组中查找某个元素,前提该数组已经排序

    例如:int[] arr = {1,5,8,12,56,89,99}

    算法:begin=0

    end = 7

    mid = (begin+end) /2

    mid = 被查找元素  --->return mid

    mid > 被查找元素  ---> end = mid-1

    mid < 被查找元素  --->begin= mid +1

    package com.JavaStudy.studyArray0608;
    
    /**
     * @Author wufq
     * @Date 2020/6/8 11:22
     */
    public class IndexArray0608 {
    
        public static void main(String[] args){
            int[] arr = {1,6,9,22,55,56,99};
            int index =myIndex(arr,100);
            System.out.println(index!=-1?"被查找的元素在arr数组中的下标是"+index:"被查找的元素不存在");
        }
    
        //myIndex方法两个元素,一个是arr数组,另外一个是需要查找的数
        public static int myIndex(int[] arr,int dest){
    
            //定义开始和结尾下标
            int begin = 0;
            int end = arr.length-1;
    
    
            while (begin <= end){
                int mid = (begin+end)/2;
                //判断中间数是否等于需要查找的数
                if(arr[mid]==dest){
                    return mid;
                }else if(arr[mid]<dest){
                    begin= mid+1;
                }else if(arr[mid]>dest){
                    end= mid -1;
                }
            }
    
            return -1;
        }
    }
    ======执行结果=====
    被查找的元素在arr数组中的下标是4

    四、数组的工具类:Arrays类 --->java.until.Arrays

    常用方法:

    sort方法:可以进行排序

    binarySearch方法:可以进行二分法排序查找

    package com.JavaStudy.studyArray0608;
    
    import java.util.Arrays;
    
    /**
     * @Author wufq
     * @Date 2020/6/8 16:20
     Arrays工具类,可以进行数组的查询和排序
     */
    public class ArraysTest01 {
        public static void main(String[] args){
            int[] arr = {1,7,9,2,6,3};
            //Arrays类里面sort方法进行排序
            Arrays.sort(arr);
    
            //逆向遍历数组
            for(int j=arr.length-1;j>=0;j--){
                System.out.print(arr[j]+" ");
            }
    
            System.out.println("
    ");
    
            //正向遍历数组
            for(int i=0;i<arr.length;i++){
                System.out.print(arr[i]+" ");
            }
    
            System.out.println("
    ");
    
            //Arrays类中的binarySearch方法可以进行二分法查找数组下标
            int index = Arrays.binarySearch(arr,3);
            System.out.println("arr数组的下标:"+index);
        }
    }
    =====执行结果=====
    9 7 6 3 2 1 
    
    1 2 3 6 7 9 
    
    arr数组的下标:2

     五、对一个字符串中的数值进行从小到大的排序

    "20 78 9 -7 88 36 29"

    思路:

    1、排序我很熟,但是只熟int

    2、如何获取到这些字符串中这些需要排序的数值

      发现这些字符串都是用空格来对数值进行分隔的,

      所以我们就想到用字符串对象的切割方法将大串切割成小串

    3、数值最终变成小字符串,但是怎么变成int类型呢

    字符串-->基本类型可以使用包装类

    package com.JavaStudy01;
    
    import java.util.Arrays;
    
    /**
     * @Author wufq
     * @Date 2020/7/29 10:57
     * 字符串"20 6 -1 50 9 7"  排序
     * 思路:
     * 之前排序的都是int类型,但是没有把string类型的数值排序过
     * 1、发现字符串是由空格进行分隔的,所以需要把大的字符串切割成小字符串
     * 2、小字符串转换成int类型进行排序
     * 3、排序后在转换成字符串
     */
    public class WrapperTest {
        private static final String SPACE_SEPARATOR = " "; //大小写切换快捷方式:⌘⇧U
    
        public static void main(String[] args){
            String numstr = "20 6 -1 50 9 7";
            System.out.println(numstr);//转换前
            numstr = toStringNum(numstr);  //自定义了一个方法名,但是想自动转换成方法,快捷方式为:option+enter/alt+enter
            System.out.print(numstr);//转换后
    
        }
    
        private static String toStringNum(String numstr) {
    
    
    /*   String [] str_num = numstr.split(" ");   --> 想把此段代码变成一个方法,需要在idea内进行重构:全部选中右键->Refactor->Extract->Method
         或者用快捷方式option+command+M
    */
            //1、将字符串变成字符串数组
            String[] str_num = stringToArray(numstr);
            //2、将字符串数组变成int数组
            int [] int_num = toIntArray(str_num);
            //3、对int数组进行排序
            mySortArray(int_num);
            //4、将排序后的int数组,转换成字符串
            String temp = arrayToString(int_num);
    
            return temp;
        }
    
        private static String arrayToString(int[] int_num) {
            StringBuilder sb = new StringBuilder();
            for(int j=0;j<int_num.length;j++){
                if(j!=int_num.length-1){
                    sb.append(int_num[j]+SPACE_SEPARATOR);
                }else {
                    sb.append(int_num[j]);
                }
            }
            return sb.toString();
        }
    
        private static void mySortArray(int[] int_num) {
            Arrays.sort(int_num);
        }
    
        public static int[] toIntArray(String[] str_num) {
            int[] arr = new int[str_num.length];
            for(int i=0;i<arr.length;i++){
                 arr[i]= Integer.parseInt(str_num[i]);
            }
            return arr;
        }
    
        public static String[] stringToArray(String numstr) {
            String [] str_num = numstr.split(SPACE_SEPARATOR);
            return str_num;
        }
    
    
    }
    ======执行结果======
    转换前:20 6 -1 50 9 7
    转换后:-1 6 7 9 20 5

     知识补充:

    String、StringBuffer和StringBuilder的区别:

    String类时不可变类,定义以后所占的内容空间不能修改

    StringBuffer和StringBuilder功能差不多,都是代表了字符序列可变的字符串,

    StringBuffer和StringBuilder创建以后,提供append(),insert(),reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列,一旦生成想要的字符串,就可以通过toString()方法将其转换成一个String对象

    两者之间的曲边:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。

    参考文章:https://blog.csdn.net/csxypr/article/details/92378336

  • 相关阅读:
    深度学习文献代码阅读-超分辨(ESRGAN)
    缺陷检测-5.Learning to Detect Multiple Photographic Defects(学习去检测多种摄像缺陷)
    缺陷检测-4.Semi-supervised Anomaly Detection using AutoEncoders(半监督缺陷检测使用自动的编码器)
    缺陷检测-3.CutPaste: Self-Supervised Learning for Anomaly Detection and Localization(剪切粘贴:自监督学习对于异常检测和定位)
    缺陷检测-2.Mixed supervision for surface-defect detection: from weakly to fully supervised learning(对于表面缺陷检测的混合监督:从弱到完全监督学习)
    缺陷检测-1.End-to-end training of a two-stage neural network for defect detection(端到端的两步神经网络的缺陷检测)(论文和代码讲解)
    Mac Docker 中运行 Linux 0.12
    Sharding-JDBC 学习
    编译型语言&解释型语言
    vnc客户端远程登录无显示器Apple macOS 主机修改分辨率的方法
  • 原文地址:https://www.cnblogs.com/frankruby/p/13043966.html
Copyright © 2011-2022 走看看