关于数组的习题

准备工作

这里设计一个类,包含了对数组的基本操作,如使用随机数初始化数组元素,输出数组元素等等。在今后的案例中,我们会根据需要,逐步向这个类中添加方法,完成更多的功能。
ArrayOP.java代码如下:

import java.util.Random;
/*
数组的基本操作
 */
public class ArrayOP {
    //init方法用于使用随机数初始化一个数组,bound表示元素的最大值
    public void init(int[] a,int bound){
        Random r=new Random();
        //使用随机值为数组元素赋值,元素值为[0,bound)
        for (int i = 0; i < a.length; i++) {
            a[i]=r.nextInt(bound);
        }
    }
    //printArray方法用于输出数组中的元素,五个一行
    public void printArray(int[] a){
        for (int i = 0; i < a.length; i++) {
            //依次输出每一个元素,用制表符隔开
            System.out.print("数组第"+i+"号元素是:"+a[i]+"\t");
            if((i+1)%5==0){
                //每输出5个元素,输出一个换行符
                System.out.println();
            }
        }
        System.out.println();
    }
    //printArrayEach是采用了for each循环的数组输出方法
    public void printArrayEach(int[] a) {
        int count=0;
        for (int i : a) {
            System.out.print("数组第" + count + "号元素是:" + i + "\t");
            if ((count + 1) % 5 == 0) {
                // 每输出5个元素,输出一个换行符
                System.out.println();
            }
            count++;
        }
    }
}

在ArrayTest01.java中调用ArrayOP.java中的方法初始化一个数组并输出。

public class ArrayTest01 {
    public static void main(String[] args) {
        int[] a=new int[100];
        ArrayOP ao=new ArrayOP();
        //初始化数组a,数组元素值限定为1000以内
        ao.init(a,1000);
        //输出元素值
        ao.printArray(a);
    }
}

03

 

冒泡法排序

冒泡法是一种常见的排序算法,其基本思路是从头至尾,将相邻的两个元素比较大小,如果前面的元素大,就交换两个元素,将大的元素放到后面。这样,经过一轮比较,就可以将最大的元素放到数组的最后。如此经过(数组长度-1)轮比较后,就可以把第一大、第二大……的元素放到数组最后、倒数第二……的位置上,从而完成整个数组的排序了。之所以是(数组长度-1)轮比较,因为这么多轮比较后,只剩一个元素还没有确定位置,但其他元素的位置都已经确定,所以这最后一个元素的位置也就不得不确定了。
我们向ArrayOP.java中添加代码:

//bubbleSort方法使用冒泡法为数组排序
    public void bubbleSort(int[] a){
        //临时变量temp
        int temp;
        for(int i=0;i<a.length-1;i++){
            for(int j=0;j<a.length-i-1;j++){
                //每一轮都会确定一个元素的位置,所以只需要在剩下的元素中比较就可以了
                //因此循环条件是j<a.length-i-1
                if(a[j]>a[j+1]){
                    //如果前面的元素比后面的大,交换位置
                    temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                }
            }
        }
    }

为了更清楚地显示冒泡法的执行过程,我们编写ArrayTest02.java程序,代码如下:

public class ArrayTest02 {
    public static void main(String[] args) {
        int[] a=new int[5];
        ArrayOP ao=new ArrayOP();
        //使用100以内的整数初始化数组元素
        ao.init(a,100);
        System.out.println("数组的元素值为:");
        ao.printArray(a);
        System.out.println("---------------------------------");
        //排序
        ao.bubbleSort(a);
        ao.printArray(a);
        System.out.println("---------------------------------");
        /*这部分程序展示了排序的过程
        //临时变量temp
        int temp;
        for(int i=0;i<a.length-1;i++){
            for(int j=0;j<a.length-i-1;j++){
                if(a[j]>a[j+1]){
                    temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                }
                System.out.println("这是第"+i+"轮中的第"+j+"次操作结果:");
                ao.printArray(a);
            }
            System.out.println("---------------------------------");
        }
        */
    }
}

运行结果为:

数组的元素值为:
数组第0号元素是:79    数组第1号元素是:27    数组第2号元素是:49    数组第3号元素是:86    数组第4号元素是:78    
---------------------------------
这是第0轮中的第0次操作结果:
数组第0号元素是:27    数组第1号元素是:79    数组第2号元素是:49    数组第3号元素是:86    数组第4号元素是:78    
这是第0轮中的第1次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:79    数组第3号元素是:86    数组第4号元素是:78    
这是第0轮中的第2次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:79    数组第3号元素是:86    数组第4号元素是:78    
这是第0轮中的第3次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:79    数组第3号元素是:78    数组第4号元素是:86    
---------------------------------
这是第1轮中的第0次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:79    数组第3号元素是:78    数组第4号元素是:86    
这是第1轮中的第1次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:79    数组第3号元素是:78    数组第4号元素是:86    
这是第1轮中的第2次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:78    数组第3号元素是:79    数组第4号元素是:86    
---------------------------------
这是第2轮中的第0次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:78    数组第3号元素是:79    数组第4号元素是:86    
这是第2轮中的第1次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:78    数组第3号元素是:79    数组第4号元素是:86    
---------------------------------
这是第3轮中的第0次操作结果:
数组第0号元素是:27    数组第1号元素是:49    数组第2号元素是:78    数组第3号元素是:79    数组第4号元素是:86    
---------------------------------

快速排序

快速排序的基本思路是,在数组中找一个元素为基准值(一般是数组中间的元素或第一个元素),然后把其他元素中比基准值大元素放到其右侧,比基准值小的元素放到其左侧,然后对左右两侧的子数组进行相同的操作,直到完成排序为止。在ArrayOP.java中添加quickSort方法:

    //快速排序法
    public void quickSort(int[] a,int leftIndex,int rightIndex) {
        //保存排序的范围
        int left=leftIndex;
        int right=rightIndex;
        //start用于保存排序时的基准值
        int start;
        //临时变量,用于交换两个元素
        int temp;
        if(rightIndex>leftIndex) {
            //将数组中间的元素设置为基准值,使用其他元素也能起到相同的效果
            start=a[(leftIndex+rightIndex)/2];
            while(left<=right) {
                //在左半边找到比基准值大的元素
                while((left<rightIndex)&&(a[left]<start)) {
                    left++;
                }
                //在右半边找到比基准值小的元素
                while((right>leftIndex) && (a[right]>start)) {
                    right--;
                }
                //将左边比基准值大的元素和右边比基准值小的元素交换位置
                if(left<=right) {
                    temp=a[left];
                    a[left]=a[right];
                    a[right]=temp;
                    left++;
                    right--;
                }
            }
            //对基准值两边的部分,再次执行上面的排序
            if(leftIndex<right) {
                quickSort(a, leftIndex, right);
            }
            if(left<rightIndex) {
                quickSort(a, left, rightIndex);
            }
        }
    }

测试时可以将ArrayTest02.java程序中的ao.bubbleSort(a);替换为ao.quickSort(a);

逆序排序

之前讲过的方法是从小到大的排序,如果我们需要从大到小排序(逆序),怎么办呢?修改代码肯定是一种方法,但如果不想过多修改代码,那么可以先按照从小到大排序,然后交换首尾元素值,把数组“翻转过来”就可以了。方法如下:

    //将数组元素头尾互换,翻转过来
    public void reverse(int[] a) {
        int temp;
        for(int i=0;i<=(a.length-1)/2;i++) {
            temp=a[i];
            a[i]=a[a.length-1-i];
            a[a.length-1-i]=temp;
        }
    }

测试时可以在ArrayTest02.java程序执行排序后,然后翻转数组,看输出结果即可。

03

 

顺序查找

最简单的查找方法就是顺序朝招,从第一个元素开始,依次比较数组元素和查找对象,如果某个元素和对象值相等,说明查找到了;如果尝试了所有的元素没有找到与查找对象相等的元素,则表示没有找到。在ArrayOP.java中添加search方法:

    //顺序查找
    public int search(int[] a,int key){
        int index=-1;
        for(int i=0;i<a.length;i++){
            if(a[i]==key){
                index=i;
                break;
            }
        }
        return index;
    }

编写ArrayTest03.java程序测试这个方法:

public class ArrayTest03 {
    public static void main(String[] args) {
        ArrayOP ao=new ArrayOP();
        //创建一个有10个元素的数组a,并使用不大于100的随机数初始化
        int[] a=new int[10];
        ao.init(a, 10);
        ao.printArray(a);
        //在数组a中查找数值5
        int index=ao.search(a, 5);
        if(index==-1) {
            System.out.println(5+"不在数组中");
        }else {
            System.out.println(5+"在数组中,位置索引值为:"+index);
        }
    }
}

二分法查找

上面的查找算法简单有效,但如果要查找的数据位于数组的结尾处,或者不存在于数组中,就需要花费较长的时间。为了缩短查找时间,我们可以采用二分法查找。二分法查找的基本思路是:先将数组排序,然后对比查找对象和中间那个元素的值,如果两者相等,则找到;如果不相等,而且中间元素比查找对象大,则到数组的左半部分继续按照前述方法查找;如果不相等,而且中间元素比查找对象小,则到数组的右半部分继续按照前述方法查找。
还记得猜数字游戏吗?我们可以使用二分法查找的思想来玩这个游戏:如果数字处于0到100之间,我们第一次就猜50(0到100的中间值),如果游戏提示我们猜小了,就猜75(50到100的中间值),如果游戏提示我们猜大了,就猜63(50到75的中间值)……由此可以提高猜对的概率。
二分法查找的思路是每次排除不正确的一半数据,因此可以大大提高查找速率。

在ArrayOP.java中添加binarySearch方法:

//二分法查找,leftIndex和rightIndex为查找的左右边界
    public int binarySearch(int[] a,int v,int leftIndex,int rightIndex) {
        //去数组中间元素的索引值
        int middle=(leftIndex+rightIndex)/2;
        //左边界不能在右边界的右边
        if(leftIndex<rightIndex) {
            if(a[middle]==v) {
                //如果中间这个元素等于v表示找到了,返回middle值
                return middle;
            }else if(a[middle]>v) {
                //如果中间元素比v大,则到数组左半边查找
                return binarySearch(a, v, leftIndex, middle-1);
            }else {
                //如果中间元素比v小,则到数组右半边查找
                return binarySearch(a, v, middle+1, rightIndex);
            }
        }
        //如果前面的程序没有结果,那么返回-1,表示没有找到
        return -1;
    }

我们改动一下ArrayTest03.java程序,让第一种方法是第二种方法的验证标准。


public class ArrayTest03 {

    public static void main(String[] args) {
        ArrayOP ao=new ArrayOP();
        //创建一个有10个元素的数组a,并使用不大于100的随机数初始化
        int[] a=new int[10];
        ao.init(a, 10);
        ao.printArray(a);
        //在数组a中查找数值50
        int index=ao.search(a, 5);
        if(index==-1) {
            System.out.println(5+"不在数组中");
        }else {
            System.out.println(5+"在数组中,位置索引值为:"+index);
        }
        //使用二分法查找
        System.out.println("------二分法查找结果------");
        //先从小到大排序
        ao.bubbleSort(a);
        ao.printArray(a);
        //开始二分法查找
        int index2=ao.binarySearch(a, 5, 0, a.length-1);
        //检查查找结果
        if(index2==-1) {
            System.out.println(5+"不在数组中");
        }else {
            System.out.println(5+"在数组中,位置索引值为:"+index2);
        }
        //对比两次查找的结果,相同输出true,不同输出false
        System.out.println((index>-1)==(index2>-1));
    }
}

03

 

最大值和最小值

在求一个数组最大值和最小值时,可以首先假设任意一个元素(一般是第一个元素)为最大值(最小值),然后和其他元素依次比较,如果发现更大(更小)的值则假设这个新发现的元素为最大值(最小值)。将所有元素都检测一遍,就能找到最大值和最小值了。
代码如下:

    // 找数组的最大值
    public int maxValue(int[] a) {
        int max = a[0];
        for (int i = 1; i < a.length; i++) {
            if (max < a[i]) {
                max = a[i];
            }
        }
        return max;
    }

    // 找数组的最小值
    public int minValue(int[] a) {
        int min = a[0];
        for (int i = 1; i < a.length; i++) {
            if (min > a[i]) {
                min = a[i];
            }
        }
        return min;
    }

我们可以编写程序Array04.java进行测试,代码如下:

public class Array04 {
    public static void main(String[] args) {
        ArrayOP ao=new ArrayOP();
        //创建一个有10个元素的数组a,并使用不大于100的随机数初始化
        int[] a=new int[10];
        ao.init(a, 100);
        //排序
        ao.quickSort(a, 0, a.length-1);
        //输出排序后的数组,第一个元素就是最小值,最后一个元素就是最大值
        ao.printArray(a);
        System.out.println("数组中的最大值为:"+ao.maxValue(a));
        System.out.println("数组中的最小值为:"+ao.minValue(a));
    }
}

Java提供的常用数组工具

  • 复制数组:System.arrayCopy(Object src, int srcPos, Object dest, int desPos, int length),参数的含义是:源数组, 源数组开始复制的位置, 目标数组, 目标数组开始存放的位置, 复制元素数量
  • 快速排序:Arrays.sort(),参数为待排序的数组名
  • 二分法查找:Arrays.binarySearch(),有两个参数,第一个为待查找的数组,第二个为要查找的值,如果找到,返回该元素的索引值;如果找不到,返回一个负数。
    下面我们使用这些方法来完成复制数组、排序和查找等数组操作:
import java.util.Arrays;
public class ArrayTest04 {
    public static void main(String[] args) {
        ArrayOP ao=new ArrayOP();
        //创建一个有10个元素的数组a,并使用不大于10的随机数初始化
        int[] a=new int[10];
        ao.init(a, 10);
        System.out.println("----------现在输出数组a的内容----------");
        ao.printArray(a);
        //复制数组中后8个元素
        int[] b=new int[8];
        System.arraycopy(a, 2, b, 0, 8);
        System.out.println("----------现在输出数组b的内容----------");
        ao.printArray(b);
        //排序
        System.out.println("----------现在输出数组a的内容----------");
        Arrays.sort(a);
        ao.printArray(a);
        //查找5是否在数组a中
        System.out.println((Arrays.binarySearch(a, 5)>=0)?("5在数组a中,索引值为"+Arrays.binarySearch(a, 5)):"5不在数组a中");
    }
}

03

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值