数组的查找

查找

  1. 顺序查找法:逐个比较,直到找到为止
  2. 二分查找法/折半查找法:重视将要查找的数和查找范围中心位置的数进行比较,如果结果只有三种:相等,大于和小于。如果大于,说明应该在后半段查找,否则应该在前半段查找,但是二分查找有一个前提是,数据必须是有序的
  3. 查找最大/最小值
  4. 冒泡排序:相邻的数两两比较,不符合顺序要求则对调,一趟下来可以安排好一个数,重复n-1趟即可将n个数排好序。
  5. 选择排序法:找出最大数的位置,将该位置的数和最后位置的数对调,重复n-1次即可。
顺序查找法

案例:

public class Demo {
    public static void main(String[] args) {
        int[]a={11,33,4,2,5,66};
        System.out.println("请输入要找的数:");
        Scanner sc = new Scanner(System.in);
        int v = sc.nextInt();
        int index = -1;
        for (int i=0;i<a.length;i++){
            if (a[i]==v){
                index=i;
                break;
            }
        }
        if (-1==index){
            System.out.println("不存在");
        }else {
            System.out.printf("%d在%d号位置",v,index);
        }
    }
}

结果:

心得体会:

  1. 顺序查找就是一个遍历加比较,这个算法最简单,但是比较次数较多,平均比较次数是n/2,基于数据量成正比
  2. 和利时用空行分割不同的逻辑块,使得程序的结构更加清晰,比如此例中划分为数据初始化,接收输入,查找,输出结果四个逻辑块。
  3. 不在查找的代码中输出结果,还是为了程序结构的清晰和合理,一般一个逻辑块就做一件事,不要糅杂在一起。
  4. 判断相等时,把常量放在前面,避免混用==和=,照成逻辑错误。
折半查找法/二分查找发

案例:

public class Demo {
    public static void main(String[] args) {
        int[]a = {1,2,3,4,5,6,7,8,9,10};
        System.out.println("请输入要找的数:");
        Scanner sc = new Scanner(System.in);
        int v = sc.nextInt();
        int left = 0;//查找范围的起始下标
        int right=a.length-1;//查找范围的终止下标
        int index = -1;//找到的位置
        while (left<=right){
            int mid = (left+right)/2;
            if (v==a[mid]){
                index = mid;
                break;
            }else if (v>a[mid]){
                left=mid+1;
            }else {
                right = mid-1;
            }
        }
        if (-1==index){
            System.out.println("不存在");
        }else {
            System.out.printf("%d在%d号位置",v,index);
        }
    }
}

结果:


心得体会:

  1. 顺序查找算法简单,代码也简单,而折半查找复杂
  2. 折半查找的小于远高于顺序查找,它最坏的情况需要找log2^n次。
  3. 折半查找的高效有前提;有序,为了保证这一点有可能付出的代价远高于查找本身。
查找最大/最小值

案例:

public class Demo {
    public static void main(String[] args) {
        int[]a={1111,22,33,3444,55,63,77};
        int max = a[0];
        int min = a[0];
        for (int i=1;i<a.length;i++){
            if (a[i]>max){
                max=a[i];
            }
        }
        for (int i=1;i<a.length;i++){
            if (a[i]<min){
                min = a[i];
            }
        }
        System.out.printf("最大值=%d\n",max);
        System.out.printf("最小值=%d",min);
    }
}

结果:

冒泡排序

案例:

public class Demo {
    public static void main(String[] args) {
        int[]a={1,34,5,67,4,2,7,3};
        for (int b:a) {
            System.out.printf("%4d",b);
        }
        System.out.println();
        for (int i=1;i<a.length-1;i++){
            for (int j=0;j<a.length-i;j++){
                if (a[j]>a[j+1]){
                    int t = a[j];
                    a[j] = a[j+1];
                    a[j+1] = t;
                }
            }
        }
        for (int x:a) {
            System.out.printf("%4d",x);
        }
        System.out.println();
    }
}

结果:

心得体会:

  1. 对于复杂问题,可以想办法降低难度,比如此案例可以先写出第一趟冒泡的程序,然后第二趟......,最后总结出规律,将其套在一个循环中即可解决。
  2. 两两比较时的对调很多时候时没有必要的,所以该方法效率不高。
  3. 该案例中,输出数组的代码写了两次,其实是有办法只写一次的,那就是函数。
选择排序法
案例:
public static void main(String[] args) {
    int []a = {2,3,5,6,88,4,11,9};
    for (int x:a){//遍历出数组
        System.out.printf("%4d",x);
    }
    System.out.println("");
    for (int n =1;n<=a.length-1;n++) {
        //(1)找最大数的位置
        int max_index = 0;
        for (int i = 1;i<=a.length-n;i++){
            if (a[i]>a[max_index]){
                max_index = i;
            }
        }
        //(2)对调
        int t = a[max_index];
        a[max_index] = a[a.length-n];
        a[a.length-n] = t;
    }
    for (int x:a){//遍历出数组
        System.out.printf("%4d",x);
    }
}

结果:

心得体会:

  1. 每一趟选择包含两个动作:找最大位置和对调,这两个功能之前都已经解决了,所以有积累的话,很多问题会越来越简单,反之就会越来越复杂。
  2. 选择排序法的效率要高于冒泡排序,因为一趟选择只有一次交换操作。
二维数组

定义:

  1. double a[][] = new double[3][6];
  2. int b[][] ={{22,33,44},{33,44,55},{33,55,66}};
案例:求5个班级哪个最优秀?
public class Demo {
    public static void main(String[] args) {
        int[]arrs=new int [5];
        int num=0;
        int arr[][]={{12,34,76,45,88,36,87},{5,67,89,36,89,65,98},
                {34,67,65,87,90,77,89,87},{67,87,56,98,76,64,34,77,},
                {56,76,87,90,65,98,55,44}};
        for (int n=0;n<arr.length;n++){
            int sum=0;
            for (int i=0;i<arr[n].length;i++){
                sum +=arr[n][i];
            }
            int avg = sum/arr[n].length;
            arrs[n] = avg;
        }
        for (int k=0;k<arrs.length;k++){
            System.out.println((k+1)+"班的平均分"+arrs[k]);
        }
        int max = arrs[0];
        for (int i=1;i<arrs.length;i++){
            if (arrs[i]>max){
                max = arrs[i];
                num = i;
            }
        }
        System.out.printf("最好的是%d班",(num+1));
    }
}

结果:




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值