Java数组

数组的定义

之前在定义数据的时候,大部分都是用变量来存储数据。可是当我们的程序中需要大量的数据,我们需要连续输入多个数字,连续输入多个坐标点,一般而言会创建多个变量存储这些数据,显得比较麻烦。当这些变量基本上类型是共通的,那我们就可以用一个容器将所有的数字进行管理。类似于字符串,字符串其实就是若干个字符的容器而已,“abc”可以通过索引/角标来获取其中某一个字符。[1,2,3,4,5]类似字符串也可以通过索引/角标来获取其中某一个数字,那么这个容器我们称之为数组。

数组的本质

数组就是一片地址连续且空间大小一致的存储空间(但是每个空间存的还是其他数据的地址)

声明数组变量

声明数组:就是告诉计算机数组的类型是什么。有两种形式:

dataType[] array; // 首选的方法

dataType array[]; // 效果相同,但不是首选方法

实例

下面是这两种语法的代码示例:

double[] myList; // 首选的方法

double myList[]; // 效果相同,但不是首选方法

分配空间:告诉计算机需要给该数组分配多少连续的空间,记住是连续的。

array = new int[10];

赋值:赋值就是在已经分配的空间里面放入数据。

array[0] = 1 、array[1] = 2……

Java中我们定义的元素是默认被赋予初值的

  • int类型:0
  • double类型:0.0
  • 布尔类型:false
  • 引用数据类型:null
import java.util.Scanner;
public class Text08{
	public static void main(String []args) {
		int []num = new int[10];
		Scanner in = new Scanner(System.in);
		for (int i = 0;i<10;i++) {
			num[i] = in.nextInt();
		}
		for (int i = 0;i<10;i++) {
			System.out.println(num[i]);
		}
	}
}

数组通过角标来访问元素的具体计算方式是 所要访问数据的地址=首元素地址+角标*数据类型大小

其实分配空间和赋值是一起进行的,也就是完成数组的初始化。有如下三种形式:

int x[] = new int[9];    //默认为0,如果是引用数据类型就为null
int y[] = new int[] {1,4,5};    
int z[] = {1,2,3};

创建数组

Java语言使用new操作符来创建数组,语法如下:

array = new dataType[arraySize];

上面的语法语句做了两件事:

  • 使用 dataType[arraySize] 创建了一个数组。
  • 把新创建的数组的引用赋值给变量 array。

创建数组时必须明确规定大小或内容。数组变量的声明,和创建数组可以用一条语句完成,如下所示:

dataType[] array = new dataType[arraySize];

数据类型[] 数组名=new 数据类型[长度];

创建数组只指定长度但不指定内容

数据类型[] 数组名=new 数据类型[]{1,2,3,4,5};

创建数组指定内容(指定长度)

另外,你还可以使用如下的方式创建数组。

dataType[] array = {value0, value1, ..., valuek};

数据类型[] 数组名={1,2,3,4,5};

创建数组指定内容(指定长度)

[]表示是一维数组

[][]表示二维数组

数组的元素是通过下标访问的。数组下标从 0 开始,所以下标值从 0 到 arrayRefVar.length-1。

实例

下面的语句首先声明了一个数组变量 myList,接着创建了一个包含 8 个 double 类型元素的数组,并且把它的引用赋值给 myList 变量。

public class TestArray {
   public static void main(String[] args) {
      // 数组大小
      int size = 10;
      // 定义数组
      double[] myList = new double[size];
      myList[0] = 5.6;
      myList[1] = 4.5;
      myList[2] = 3.3;
      myList[3] = 13.2;
      myList[4] = 4.0;
      myList[5] = 34.33;
      myList[6] = 34.0;
      myList[7] = 45.45;
      myList[8] = 99.993;
      myList[9] = 11123;
      // 计算所有元素的总和
      double total = 0;
      for (int i = 0; i < size; i++) {
         total += myList[i];
      }
      System.out.println("总和为: " + total);
   }
}

 以上实例输出结果为:

总和为: 11367.373

下面的图片描绘了数组 myList。这里 myList 数组里有 10 个 double 元素,它的下标从 0 到 9。

java数组结构说明

处理数组

数组的元素类型和数组的大小都是确定

该实例完整地展示了如何创建、初始化和操纵数组

public class TestArray {
   public static void main(String[] args) {
      double[] myList = {1.9, 2.9, 3.4, 3.5};
 
      // 打印所有数组元素
      for (int i = 0; i < myList.length; i++) {
         System.out.println(myList[i] + " ");
      }
      // 计算所有元素的总和
      double total = 0;
      for (int i = 0; i < myList.length; i++) {
         total += myList[i];
      }
      System.out.println("Total is " + total);
      // 查找最大元素
      double max = myList[0];
      for (int i = 1; i < myList.length; i++) {
         if (myList[i] > max) max = myList[i];
      }
      System.out.println("Max is " + max);
   }
}

以上实例编译运行结果如下:

1.9
2.9
3.4
3.5
Total is 11.7
Max is 3.5

数组常见错误:

ArrayIndexOutOfBoundsException            数组角标越界

NullPointerException                                  空指针异常

数组内存

数组存在于堆内存中,数组变量存的就是数组在堆内存中首元素的地址

  • 但凡在堆中存储的数据都称之为对象
  • 但凡在堆内存中创建的对象都会有默认初始值

数组操作中,在栈内存中保存的永远是数组的名称,只开辟了栈内存空间数组是永远无法使用的,必须有指向的堆内存才可以使用,要想开辟新的堆内存则必须使用new关键字,之后只是将此堆内存的使用权交给了对应的栈内存空间,而且一个堆内存空间可以同时被多个栈内存空间指向,即:一个人可以有多个名字,人就相当于堆内存,名字就相当于栈内存。

遍历

数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环,尤其是for循环。JDK 1.5 引进了一种新的循环类型,被称为 for-each 循环或者加强型循环,它能在不使用下标的情况下遍历数组。

语法格式如下:

for(type element: array)
{
    System.out.println(element);
}

该实例用来显示数组 myList 中的所有元素:

public class TestArray {
   public static void main(String[] args) {
      double[] myList = {1, 2, 3, 5};
 
      // 打印所有数组元素
      for (double element: myList) {
         System.out.println(element);
      }
   }
}

以上实例编译运行结果如下:

1
2
3
5

最大值/最小值

先给数组赋值,然后调用函数求最大值:

import java.util.Scanner;
public class Text08{
	public static int max(int []a){
		int max = a[0];
		for (int i =0;i<a.length;i++) {
			if (a[i]>max) max = a[i];
		}
		return max;
	}
	public static void main(String []args) {
		int []num = new int[]{1,2,3,4,5,6,7,8,9,10};
		Scanner in = new Scanner(System.in);
		int max= max(num);
		System.out.println(max);
	}
}

我们通过函数将num数组中最大值通过遍历找出来,最后返回主函数输出

再给数组赋值,然后调用函数求最小值:

import java.util.Scanner;
public class Text08{
	public static int min(int []a){
		int min = a[0];
		for (int i =0;i<a.length;i++) {
			if (a[i]<min) min = a[i];
		}
		return min;
	}
	public static void main(String []args) {
		int []num = new int[]{1,2,3,4,5,6,7,8,9,10};
		Scanner in = new Scanner(System.in);
		int min= min(num);
		System.out.println(min);
	}
}

查找操作

线性查找

定义:

在一列给定的值中进行搜索,从一端开始逐一检查每个元素,直到找到所需元素的过程。

线性查找又称为顺序查找。如果查找池是某种类型的一个表,比如一个数组,简单的查找方法是从表头开始,一次将每一个值与目标元素进行比较。最后,或者查找到目标,或者达到表尾,而目标不存在于组中,这个方法称为线性查找

import java.util.Scanner;
class Text08{
	public static void main(String []args) {
		int []num = new int[]{1,2,3,4,5,6,7,8,9,10};
		Scanner in = new Scanner(System.in);
		int key = 11;
		int m = 0 ;
		boolean find = false;
		for (int i = 0;i<num.length;i++) {
			if (num[i]==key) {
				find = true;
				m = i+1;
			}
		}
		if(find) {
			System.out.println("第"+m+"个");
		}else {
			System.out.println("没找到");
		}
	}
}

二分查找

定义

二分查找又称折半查找,它是一种效率较高的查找方法。

二分查找要求

  • 必须采用顺序存储结构 
  • 必须按关键字大小有序排列。

优缺点

折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。

import java.util.Scanner;
class Text08{
	public static void main(String []args) {
		int []num = new int[]{1,2,3,4,5,6,7,8,9,10};
		Scanner in = new Scanner(System.in);
		int key = 2;
		int left = 0;
		int right = num.length-1;
		int mid = (left+right)/2;
		boolean flag = true;
		while (num[mid]!=key) {
			if (num[mid]>key) {
				right = mid-1;
				mid = (left+right)/2;
			}
			if (num[mid]<key) {
				left = mid+1;
				mid = (left+right)/2;
			}
			if (left>right) {
				flag = false ;
				break;
			}			
		}
		if (flag) {
			System.out.print(mid);
		}else {
			System.out.print("no find");
		}
	}
}

*斐波那契查找

黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。0.618被公认为最具有审美意义的比例数字,这个数值的作用不仅仅体现在诸如绘画、雕塑、音乐、建筑等艺术领域,而且在管理、工程设计等方面也有着不可忽视的作用。因此被称为黄金分割。

斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(从第三个数开始,后边每一个数都是前两个数的和)。然后我们会发现,随着斐波那契数列的递增,前后两个数的比值会越来越接近0.618,利用这个特性,我们就可以将黄金比例运用到查找技术中。

斐波那契搜索是在二分查找的基础上根据斐波那契数列进行分割的。在斐波那契数列找一个等于略大于查找表中元素个数的数F[n],将原查找表扩展为长度为F[n](如果要补充元素,则补充重复最后一个元素,直到满足F[n]个元素),完成后进行斐波那契分割,即F[n]个元素分割为前半部分F[n-1]个元素,后半部分F[n-2]个元素,找出要查找的元素在那一部分并递归,直到找到。
 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值