一维数组:一条线
一维数组
二维数组:一个面
二维数组
三维数组:一个立方体,三维数组使用较少,这里不提及。
一维数组
数组的创建
声明方式:如int a[]; 或者 int [] a;
Java中使用new关键字创建数组对象,格式为
int [] s = new int[5];
那么创建数组时,内存中的情况如何呢?
然后是引用类型的数组的创建:看这样一段代码
class Date{
int year,month,day;
Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
}
public class TestArray {
public static void main(String[] args) {
// TODO Auto-generated method stub
Date[] days ;
days = new Date[3];
for(int i = 0;i < 3;i++){
days[i] = new Date(2018,9,21);
}
}
}
这段代码执行时,内存是如何变化的呢?
图片.png
数组的初始化 (数组是:必须把空间分配好了,才可以往里面装值)
动态初始化
数组定义与数组元素分配空间和赋值的操作分开进行。
如:int[] a = new int[3];
静态初始化
在定义数组的同时就为数组元素分配空间并赋值。
如:int [] a = {3,9,8};
数组元素默认初始化
数组是引用类型,它的元素相当于类的成员变量,因此数组分配空间后,每个元素也被按照成员变量的规则被隐式初始化。也就是说int类型的初始化为0,引用类型初始化为null等。
数组元素的引用
定义并用运算符new为之分配空间后,才可以引用数组中的每个元素,数组元素的引用方式为:arrayName[index],index为数组元素下标,可以是整型常量或者整型表达式。如a[3],b[i],c[6*i]。数组元素的下标从0开始,长度为n的数组合法取值范围为:0~n-1。每个数组的length属性都能指明其长度。
冒泡排序:
冒泡排序的原理就是:(从小到大)将每一个元素与其之后的一个元素比较,即a[i]与a[i+1]进行比较,如果a[i] > a[i+1],定义一个中间变量temp,使temp = a[i];a[i] = a[i+1];a[i+1] = temp;将a[i]和a[i+1]的值交换。因为每一个数都要与其之后的每个数进行比较,因此,需要进行嵌套循环,代码如下:
//冒泡排序
int temp ;//中间变量
for(int k = 0 ; k < arrays.length ; k++){
for (int i = 0 ; i < arrays.length - 1 ; i++) {
if(arrays[i] > arrays[i+1]){
temp = arrays[i];
arrays[i] = arrays[i+1];
arrays[i + 1] = temp;
}
}
}
选择排序
从小到大排序,拿出第一个数,与后面的每个数进行比较,如果第一个数大于后面的数,就进行交换,这样下来就把最小的数找出了,再拿出第二个数与后面的每个数进行比较...依次类推,每一个数都与其后的每个数进行比较,如果大就交换,那么循环完成,排序就完成了,代码如下:
int temp;
for(int i= 0;i<arrays.length;i++){
for(int j = i+1;j<arrays.length;j++){
if(arrays[i]>arrays[j]){
temp = arrays[i];
arrays[i] = arrays[j];
arrays[j] = temp;
}
}
}
选择排序高效率版
原理:一次遍历只做一次交换,标记最小值的位置,用一个变量记录该位置,之前遍历交换值,现在交换位置,遍历完成之后,再将值进行交换。
int k,temp;
for (int i = 0; i < arrays.length; i++) {
k = i;
for(int j = k+1;j<arrays.length;j++){
if(arrays[j] < arrays[k]){
k = j;//position的交换,经过循环,可以把最小值的位置找出
}
}
if(k != i){
//找出最小的位置后,如果不是被比较的数,那么再把位置上的数进行交换
temp = arrays[i];
arrays[i] = arrays[k];
arrays[k] = temp;
}
}
练习:500个人拉成一圈,循环123报数,逢3退1,最后500个人只剩一人,请问,这个最后剩下的人一开始是第几个人?
/**
* 500个人拉成一圈,循环123报数,逢3退1,
* 最后500个人只剩一人,
* 请问,这个最后剩下的人一开始是第几个人?
*
* 使用数组的思路
*/
boolean[] arr = new boolean[500];//只要还在圈里的 都是true
for(int i = 0; i< arr.length;i++){
//一开始全部都在圈里
arr[i] = true;
}
int leftCount = arr.length;//剩下的人数 初始化为500
int countNum = 0;//记录报数的变量
int index = 0;//position
while(leftCount > 1){
//只要剩下的人数>1个,就进入循环
if(arr[index] == true){
countNum ++;//只要在圈中就要报数
if(countNum == 3){
//报数到3
countNum = 0;//清零 再重新报数
arr[index] = false;//报数到3 置为false 相当于出圈
leftCount -- ;//剩下的人-1
}
}
index ++;//每循环一次,index+1
if(index == arr.length){
//一圈下来,index置为0,再开始新的一圈
index = 0;
}
}
//循环结束,圈里还剩一个人为true,找出这个人
for(int i = 0;i < arr.length; i++){
if(arr[i] == true){
System.out.println(i+" ");
}
}
二分查找法
查找都是在排序排好的基础上进行的,所谓二分查找法,是在排序排好的数组中,从中间的位置开始找,直到找到要找的值为止。
//二分查找
public static int binarySearch(int[] a,int i){
if(a.length == 0){
return -1;
}
int startPos = 0;
int endPos = a.length - 1;
int m = (startPos + endPos) / 2;
while(startPos <= endPos){
if(i == a[m]){
//如果要查找的值,刚好等于中间值
return m;
}
if(i > a[m]){
//如果要查找的值,比中间值大,说明在中间值的右边
startPos = m + 1;//更改起始位置
}
if(i < a[m]){
//如果要查找的值,比中间值小,说明在中间值的左边
endPos = m - 1;//更改结束位置
}
//一次循环结束,更改m
m = ( startPos + endPos ) / 2;
}
return -1;
}
二维数组
二维数组可以看成已数组为元素的数组。如:
int a[][] = {{1,2},{3,4,5},{7,8,9}};
二维数组的声明和初始化应该从高维到低维的顺序进行(也就是从左到右),如:
int a[][] = new int[3][];//合法
int a[][] = new int[][4];//非法
二维数组在内存中的情况如下:
二维数组在内存中的情况
二维数组的初始化
静态初始化
int a[][] = {{1,2},{3,4,5},{7,8,9}};
动态初始化
int a[][] = new int[3][5];
int b[][] = new int[3][];
b[0] = new int[2];
b[1] = new int[3];
b[2] = new int[5];
数组的拷贝
System.arraycopy(Object srcArr,int srcPos,Object dest,int destPos,int length);
数组srcArr从srcPos项元素开始的length个元素拷贝到dest数组从destPos项开始的length个位置。
数组结束。下一章常用类
欢迎关注个人公众号,加入进来一起学习吧!
平头哥写代码
网友评论