自学内容网 自学内容网

Java学习笔记--数组常见算法:数组翻转,冒泡排序,二分查找

一,数组翻转

1.概述:数组对称索引位置上的元素互换,最大值数组序号是数组长度减一

创建跳板temp,进行min和max的互换,然后min自增,max自减,当min>=max的时候停止互换,代表到中间值

用代码实现

public class Demo01Reverse {
    public static void main(String[] args) {
        //定义一个静态数组 
        int arr [] ={1,2,3,4,5,6,7};
        for(int min=0,max = arr.length-1;min<max;min++,max--){
            //进行换位
            int temp = arr[min];
            arr[min]= arr[max];
            arr[max]= temp;

        }


        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
}

二,冒泡排序


 数组的排序,是将数组中的元素按照大小进行排序,默认都是以升序的形式进行排序,数组排序的方法很多,我们讲解的是数组的冒泡排序。

  排序,都要进行数组 元素大小的比较,再进行位置的交换。冒泡排序法是采用数组中相邻元素进行比较换位。
  arr[i](前一个元素)   arr[i+1](后一个元素)

比如以下数组

5 4 3 2 1

进行0,1号位的数字比较

4 5 3 2 1

然后又进行1,2号位的数字比较

4 3 5 2 1

然后2,3号位比较

4 3 2 5 1

最后3,4号位比较

4 3 2 1 5

实现位置的交换依然和前面数组翻转一样,创建一个跳板temp进行交换

代码实现

首先,定义数组

public class Demo02Bubble {
    public static void main(String[] args) {
        int[] arr = {5,4,3,2,1};

进行第一轮冒泡

/* 第一圈 */
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr [i+1];
                arr[i+1] = temp;

            }
        }

测试,出现警告

这是为什么呢

其实是循环的时候突破了数组的最大序号

因为arr.length就等于5,所以i能取到的最大值是4,所以i+1=5,突破了最大限制

改为arr.length-1

成功,然后进行第二圈

//第二圈
        for (int i = 0; i < arr.length-1; i++) {
             if(arr[i]>arr[i+1]){
                 int temp = arr[i];
                 arr[i] = arr [i+1];
                 arr[i+1] = temp;

             }
         }

第二圈代码和第一圈一样,也没问题,但也和第一圈一样比较了4次,但我们可以不必做这个重复功,因为第一次比较完了一个数,所以我们可以减去一次循环来表示可以少比较的次数,所以可以写成arr.length-1-1,最后面减的这个数可以看成是前面冒泡过的数的个数(圈数)

//第二圈
        for (int i = 0; i < arr.length-1-1; i++) {
             if(arr[i]>arr[i+1]){
                 int temp = arr[i];
                 arr[i] = arr [i+1];
                 arr[i+1] = temp;

             }
         }

现在进行第三圈第四圈,同样我们减去前面冒泡过的数的个数

//第三圈

        for (int i = 0; i < arr.length-1-2; i++) {
            if(arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr [i+1];
                arr[i+1] = temp;

            }
        }

//第四圈
        for (int i = 0; i < arr.length-1-3; i++) {
            if(arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr [i+1];
                arr[i+1] = temp;

            }
        }

运行结果

但我们可以再进行优化,这几圈的变化非常细微,只有一个数一个位置在变

如果最后面减的数是前面的圈数的话,那也就等于i啊,我们可以再在外面套一层循环,利用自加i来代替这几圈唯一变的减数

/*
外层循环代表比较了几圈
           n-1圈
*/
        for (int j = 0; j < arr.length-1; j++) {
            for (int i = 0; i < arr.length-1-j; i++) {
            /*
              内层循环代表每一圈比较的次数
              每圈都少比较一次
            */
                if(arr[i]>arr[i+1]){
                    int temp = arr[i];
                    arr[i] = arr [i+1];
                    arr[i+1] = temp;

                }
            }
        }

由此而来,化繁为简,减小了时间,空间复杂度

完整代码如下

public class Demo02Bubble {
    public static void main(String[] args) {
        int[] arr = {5,4,3,2,1};


        /*
           第一圈
             越界原因:当i变化到4的时候-> arr[4]>arr[5] -> 直接操作了5索引,所以越界了
             越界解决:我们可以让arr.length-1
                     如果arr.length-1-> 比较就是i<4 -> 此时i最大可以变化到3
                     当i变化到3时 -> arr[3]>arr[4] -> 正好是最后两个元素进行比较
         */
        for (int i = 0; i < arr.length-1-0; i++) {
            if(arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr [i+1];
                arr[i+1] = temp;

            }
        }

        
        //第二圈
        /*for (int i = 0; i < arr.length-1-1; i++) {
             if(arr[i]>arr[i+1]){
                 int temp = arr[i];
                 arr[i] = arr [i+1];
                 arr[i+1] = temp;

             }
         }*/
        //第三圈


        /*for (int i = 0; i < arr.length-1-2; i++) {
            if(arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr [i+1];
                arr[i+1] = temp;

            }
        }*/

        //第四圈
        /*for (int i = 0; i < arr.length-1-3; i++) {
            if(arr[i]>arr[i+1]){
                int temp = arr[i];
                arr[i] = arr [i+1];
                arr[i+1] = temp;

            }
        }*/


        /*
           外层循环代表比较了几圈
           n-1圈
         */
        for (int j = 0; j < arr.length-1; j++) {
            for (int i = 0; i < arr.length-1-j; i++) {
                /*
              内层循环代表每一圈比较的次数
              每圈都少比较一次
             */
                if(arr[i]>arr[i+1]){
                    int temp = arr[i];
                    arr[i] = arr [i+1];
                    arr[i+1] = temp;

                }
            }
        }


        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
}

三,二分查找(一尺之锤,日取其半,万世不竭)

1.前提:数组中的数据必须是有序的
2.查询思想:
  a.老式查询:遍历数组,一个一个比较 -> 查询效率慢
  b.二分查找:每次找中间索引对应的元素进行比较查询(每一次查询少一半数据)

首先,因为min和max会因为查找数所在数组的位置不同而改变所以不能定义min就是arr[0]或max就是arr[8],min默认为0,max为arr.length-1,mid就是二者取中。

key为查询数,是指想查的数组中的数,查询出的是数组序数代表 含的数。

前提:当min<=max时

当查询数大于或小于数组序数上所代表的数时,通过移动min和max直接排掉一半的数,来不断的锁定范围,直到找到查询数所在的位置(这个方法很像一尺之锤,日取其半,万世不竭,不过是有目标的取),当查询数等于数组序数上所代表的数时,停止查找,返回序数表示找到了。

当然还有特殊情况,就是查询数不存在在数组中,那么当min>max时,就不找了,返回-1表示找不到。

代码实现

public static int binary(int[] arr,int data){
        //定义三个变量,分别代表最大索引,最小索引,中间索引
        int min = 0;
        int max = arr.length-1;
        int mid = 0;
        //查找
        while (min<=max){
            mid = (min+max)/2;
            if(data>arr[mid]){
                min = mid+1;
            }else if(data<arr[mid]){
                max = mid-1;
            }else{
                return mid;
            }
        }

        return -1;

    }

我们发现代码实现和理论方法步骤不同,没有在一开始表示mid = (min+max)/2,因为要循环的算中间索引,在一进入循环时,在while(外层循环)内,再进行计算。

在main函数内调用方法进行输出,完整代码如下

public class Demo03Binary {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9};
        int index = binary(arr, 7);
        System.out.println(index);

    }

    public static int binary(int[] arr,int data){
        //定义三个变量,分别代表最大索引,最小索引,中间索引
        int min = 0;
        int max = arr.length-1;
        int mid = 0;
        //查找
        while (min<=max){
            mid = (min+max)/2;
            if(data>arr[mid]){
                min = mid+1;
            }else if(data<arr[mid]){
                max = mid-1;
            }else{
                return mid;
            }
        }

        return -1;

    }
}

输入7


原文地址:https://blog.csdn.net/THRUSTER11111/article/details/143882642

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!