Robin1985

导航

 

Java中提供了一种称作数组(array)的数据结构,可以用它来存储具有相同类型的变量集合。

声明数组变量

​ 如同其他使用数据类型使用一样,使用数组必须先声明数组变量,并指明数组的元素类型。声明数组变量的语法:

  • 元素类型[] 数组引用变量; (推荐使用这种,阅读感更强)

  • 元素类型 数组引用变量[];

    举例:

1 int[] arr1;
2 int arr2[];

创建数组

​ 声明一个数组变量时,并不在内存中给数组分配任何空间。它只是创建一个对数组的引用的存储位置。如果变量不包含对数组的引用,那么这个变量的值为null。除非数组已经被创建,否则不能给它分配任何元素。创建数组的语法:

  • 元素类型[] 数组引用变量 = new 元素类型[数组大小];(数组创建但未添加元素)

  • 元素类型 数组引用变量[] = new 元素类型[数组大小];(数组创建但未添加元素)

  • 元素类型[]数组引用变量 = new 元素类型[];(数组创建同时添加元素)

  • 元素类型 数组引用变量[] = new 元素类型[];(数组创建同时添加元素)

    举例:

1 int[] arr1 = new int[5];
2 int arr2[] = new int[5];
3 int[] arr3 = new int[] {1,2,3,4,5};
4 int arr4[] = new int[] {1,2,3,4,5};

数组大小和默认值

当给数组分配空间时,必须通过指定该数组能够存储的元素个数来确定数组大小。数组一旦创建,就不能再修改它的大小。可以使用数组.length获得该数组的大小。

当数组创建后,它的元素被赋予默认值,byte、short、int、long型为0,float、double型为0.0,boolean型为false,char型为'\u0000'。

获取数组下标变量

数组元素可以通过下标来访问。数组下标是基于0的,起止范围从0到数组.length-1结束。

处理数组

​ 处理数组的常用举例:

使用输入值初始化数组

1 /**
2  * 循环遍历给数组赋值
3  */
4 public static void inputNumToArray(int[] array) {
5     Scanner input = new Scanner(System.in);
6     for (int i = 0; i < array.length; i++) {
7         array[i] = input.nextInt();
8     }
9 }

使用随机数初始化数组

1 /**
2  * 使用随机数初始化数组
3  */
4 public static void randomNumToArray(int[] array) {
5     for (int i = 0; i < array.length; i++) {
6         array[i] = (int) (Math.random()*10);
7         System.out.println(array[i]);
8     }
9 }

显示数组

1 /**
2  * 打印数组中所有元素
3  */
4 public static void printNumToArray(int[] array) {
5     for (int i = 0; i < array.length; i++) {
6         System.out.println(array[i]);
7     }
8 }

对所有元素求和

 1 /**
 2  * 计算数组中所有元素之和
 3  */
 4 public static int randomNumToArray(int[] array) {
 5     int total = 0;
 6     for (int i = 0; i < array.length; i++) {
 7         total += array[i];
 8     }
 9     return total;
10 }

找出最大元素

 1 /**
 2  * 获取数组中元素最大值
 3  */
 4 public static int getMaxNumToArray(int[] array) {
 5     int max = array[0];
 6     for (int i = 0; i < array.length; i++) {
 7         if (max < array[i]) {
 8             max = array[i];
 9         }
10     }
11     return max;
12 }

找出最大元素的最小下标值

 1 /**
 2  * 获取数组中元素最大值的最小角标
 3  */
 4 public static int getMaxIndexNumToArray(int[] array) {
 5     int max = array[0];
 6     int index = 0;
 7     for (int i = 0; i < array.length; i++) {
 8         if (max < array[i]) {
 9             max = array[i];
10             index = i;
11         }
12     }
13     return index;
14 }

随意打乱

 1 /**
 2  * 获取打乱了的数组
 3  */
 4 public static int[] randomArrayToArray(int[] array) {
 5     int index = 0;
 6     int temp = 0;
 7     for (int i = 0; i < array.length; i++) {
 8         index = (int) (Math.random() * array.length);
 9         temp = array[i];
10         array[i] = array[index];
11         array[index] = temp;
12     }
13     return array;
14 }

移动元素

 1 /**
 2  * 整体左移一位,最左边的移到最右边
 3  */
 4 public static int[] startNumToEnd(int[] array) {
 5     int temp = array[0];
 6     for (int i = 1; i < array.length; i++) {
 7         array[i - 1] = array[i];
 8     }
 9     array[array.length - 1] = temp;
10     return array;
11 }

逆向输出

 1 /**
 2  * 逆向输出数组顺序
 3  */
 4 public static int[] backArray(int[] array) {
 5     int temp = 0;
 6     for (int i = 0; i < array.length / 2; i++) {
 7         temp = array[i];
 8         array[i] = array[array.length - 1 - i];
 9         array[array.length - 1 - i] = temp;
10     }
11     return array;
12 }

for-each循环

​ Java提供一种简便的for循环,称之为for-each循环(for-each loop)增强for循环(enhanced for loop),不使用下标变量就可以顺序的遍历整个数组。语法如下:

​ for (元素类型 元素 : 数组) {

​ }

​ 但是,当需要以其他顺序遍历数组或改变数组中的元素时,还是必须使用下标变量。

值传递

​ 一个对象变量并没有实际包含一个对象,而仅仅引用了一个对象。该变量不会自动初始化为null,而是必须通过调用new或将它们设置为null进行初始化。

​ Java总是采用值调用,也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。例如基本数据类型:

 1 public static void main(String[] args) {
 2       int a = 30;
 3       updateNum(a);
 4       System.out.println("a =" + a);
 5 }
 6 public static void updateNum(int b) {
 7       b = 20;
 8       System.out.println("b =" + b);
 9 }
10 console:
11 b = 20
12 a = 30

​ 执行流程:

  1. 程序将变量a的副本传递到updateNum()方法。

  2. 在updateNum()方法内,对变量a的副本进行了修改,但并未对变量a进行修改。

  3. 当程序执行完updateNum()方法后,变量a副本的值为30,最后副本被抛弃。

  4. 程序回到main函数,继续执行真正的变量a。

    ​可以看到main方法下的num打印结果不变依旧3o。一个方法不可能修改一个基本数据类型的参数。而引用数据类型作为参数就不同了。引用数据类型:

 1 public static void main(String[] args) {
 2       int[] arrA = new int[1]{30};
 3       updateArrNum(arrA);
 4       System.out.println("arrA[0] =" + arrA[0]);
 5 }
 6 public static void updateArr(int[] arrB) {
 7       arrB[0] = 20;
 8       System.out.println("arrB[0] =" + arrB[0]);
 9 }
10 console:
11 arrB[0] = 20
12 arrA[0] = 20

​ 执行流程:

  1. 程序将数组arrA引用的副本传递给updateArr()方法。

  2. 在updateArr()方法内,对数组arrA引用的副本进行了重新赋值值。注意:虽然是对副本进行重新赋值,但是arrA与arrA的副本引用的是同一块内存地址。

  3. 当重新赋值时,原始的arrA的值也变了。

数组的复制

​ 更多时候数组的复制,并不希望对内存地址的复制,而是希望对数组中的元素进行复制。通常可以使用循环遍历,逐个对元素进行复制。示例如下:

1 public static void main(String[] args) {
2       int[] arrA = new int[5]{10, 20, 30, 40, 50};
3       int[] arrB = new int[arrA.length];
4       for (int i = 0; i < arrA.length, i++) {
5            arrB[i] = arrA[i];
6       }
7 }

数组的查找

查找(searching)是在数组中寻找特定元素的过程。常用的查找有线性查找(linear searching)二分查找(binary searching)

线性查找

​ 线性查找将要查找的关键字key与数组中的元素逐个进行比较。这个过程持续到在列表中找到与关键字匹配的元素,或者查完列表也没找到关键字为止。如果匹配成功,返回与关键字匹配的元素在数组中的下标。如果没有匹配成功,则返回-1。线性查找示例如下:

1 public int linearSearching(int[] arr, int key) {
2       for (int i = 0; i < arr.length; i++) {
3           if (arr[i] == key) {
4               return i;
5           }
6           return -1;
7       }
8 }

线性查找法把关键字和数组中的每一个元素进行比较,由于线性查找方法的执行时间随着数组元素个数的增长而线性增长,所以,对于大数组而言,线性查找法的效率并不高。

二分查找法

​ 使用二分查找法的前提条件是数组中的元素必须已经排好序。假设数组已按升序排列,二分查找法首先将关键字与数组的中间元素进行比较。主要考虑三种情况:

  • 如果关键字小于中间元素,只需要在数组的前一半元素中继续查找关键字。

  • 如果关键字和中间元素相等,则匹配成功,查找结束。

  • 如果关键字大于中间元素,只需要在数组的后一半元素中继续查找关键字。

    实现思路:每次比较后,数组要查找的部分就会缩小一半。用low和high分别表示当前查找数组的第一个下标和最后一个下标。初始条件下,low为0,而high为list.length-1。让mid表示列表的中间元素的下标。这样,mid就是(low + high) /2 。如果找到这个关键字,或者当low>high时还没有找到这个关键字,就结束查找。二分查找示例如下:

 1 public int binarySearch(int[] array, int key) {
 2       //设置数组元素最小角标
 3       int low = 0;
 4       //设置数组元素最大角标
 5       int high = array.length - 1;
 6       //设置数组元素中间角标
 7       int mid = 0;
 8       while (high >= low) {
 9           mid = (low + high) / 2;
10           if (array[mid] < key) {
11               low = mid + 1;
12           } else if (array[mid] == key) {
13               return mid;
14           } else {
15               high = mid - 1;
16           }
17       }
18       return -1;
19 }

​ 二分查找法的效率较高,但它要求数组已经排序。

数组的排序

​ 数组的排序有多种方法,比较简单、直观的排序算法有:选择排序法(selection sort)插入排序法(insertion sort)

选择排序

​ 假设要按照从小到大排列一个数列。选择排序法先找到数列中最小的数,然后将它放在数列的最前面。接下来,在剩下的数中找到最小数,将它放到第一个数的后面,以此类推,知道数列中仅剩一数为止。选择排序示例如下:

 1 public static int[] selectionSort(int[] array) {
 2       for (int i = 0; i < array.length - 1; i++) {//倒数第二次已经找到所有位置,不需要进行最后一次遍历
 3           for (int j = i + 1; j < array.length; j++) {//一旦位置找到,下一次遍历是就不需要再考虑它原有位置
 4               if (array[i] > array[j]) {
 5                     int temp = array[i];
 6                     array[i] = array[j];
 7                     array[j] = temp;
 8               }            
 9           }
10       }
11 }

冒泡排序

冒泡排序算法在每次遍历中,对相邻的两个元素进行比较。如果这一对元素是降序,则交换它们的值,否则,保持值不变。由于较小的值像气泡一样逐渐“浮向”顶部,同时较大的值“沉向”底部,所以这种技术称为冒泡排序法(bubble sort)。冒泡排序示例如下:

 1 public static int[] bubbling(int[] array) {
 2     for (int i = 0; i < array.length - 1; i++) {
 3         for (int j = 0; j < array.length - i - 1; j++) {//随着每次冒泡,递减对比
 4             if (array[j] > array[j+1]) {//当小于数组前面的元素大于后面的元素时,交换位置
 5                 int temp = array[j];
 6                 array[j] = array[j+1];
 7                 array[j+1] = temp;
 8             }
 9         }
10     }
11     return array;
12 }

 

posted on 2017-03-20 22:14  Robin1985  阅读(108)  评论(0)    收藏  举报