Java数据结构与算法学习——数组
一、Java数组介绍
在Java中,数组是用来存放同一种数据类型的集合,并且只能存放同一种数据类型(Object类型的数组除外)。
1、数组的声明
第一种方式:
数据类型 [] 数组名称 = new 数据类型[数组长度]
这里[]的位置也可以放在数组名称的后面,但是没有上面看上去那么直观。
第二种方式:
数据类型 [] 数组名称={数组元素1,数组元素2,....}
这种声明方式直接给定了数组的元素,数组的大小由元素的个数决定。
//声明数组1,声明一个长度为5,只能存放int类型的数据
int [] myArray = new int[5];
//声明数组2,添加任意数组元素
int [] myArray = {1,2,3,4,5};
2、访问数组元素以及给数组元素赋值
数组有下标索引的,通过下标可以获取到指定位置的元素,下标从0开始,表示数组中的第一个元素。
对数组进行初始化赋值:
//声明数组,长度为5,int类型
int [] myArray = new int[5];
//为数组第一个元素赋值
myArray[0] = 1;
//输出元素值
System.out.println(myArray[0]);
上面的数组只能赋值5个元素,当超出数组的长度。那么会报数组下标越界异常。
3、数组遍历
数组有个length属性,能够记录数组的长度,可以使用length属性进行数组的遍历,注意:数组最后一个元素的下标索引为length-1。
//声明一个int类型的数组,元素有1,2,3
int [] myArray2 = {1,2,3};
for(int i=0; i<myArray2.length; i++){
System.out.println(myArray2[i]);
}
二、用类封装数组实现数据结构
一个数据结构必须具有以下基本功能:
1、如何插入一条新的数据项
2、如何寻找某一特定的数据项
3、如何删除某一特定的数据项
4、如何迭代的访问哥哥数据项,以便进行显示或其他操作
封装一个数组类,这里没有考虑重复元素的插入,用于实现上述功能,代码如下:
public class Demo1 {
//定义一个数组
private int [] intArray;
//定义数组的实际有效长度
private int elems;
//定义数组的最大长度
private int length;
//默认构造一个长度为50的数组
public Demo1() {
// TODO Auto-generated constructor stub
elems=0;
length=50;
intArray=new int[length];
}
//构造函数,初始化一个长度为length的数组
public Demo1(int length)
{
elems=0;
this.length=length;
intArray=new int[length];
}
//获取数组的有效长度
public int getSize() {
return elems;
}
//遍历显示元素
public void display() {
for (int i = 0; i < elems; i++) {
System.out.println(intArray[i]+" ");
}
System.out.println();
}
//添加元素
//假设不添加重复元素,添加成功返回true,失败返回false
public boolean add(int value) {
if(elems==length) {
return false;
}else {
intArray[elems]=value;
elems++;
}
return true;
}
//根据下标获取元素
//数组的下标要在有效范围内,一旦超出数组的下标的最大值
//提示数组下标越界
public int get (int i) {
if(i<0||i>elems)
{
System.out.println("访问下标越界");
}
return intArray[i];
}
//查找元素
//根据元素的下标查找,如果存在,返回下标值,不存在,返回-1
public int find(int value) {
int i;
for ( i = 0; i < elems; i++) {
if(intArray[i]==value)
{
System.out.println(intArray[i]);
break;
}
}
if(i==elems)
{
return -1;
}
return i;
}
//删除元素
//如果删除的值不存在,返回false,否则返回true
public boolean delete(int value) {
int i=find(value);
if(i==-1)
{
return false;
}else {
if(i==elems-1) {
elems--;
}else {
for (int j = 0; j < elems-1; j++) {
intArray[j]=intArray[j+1];
}
elems--;
}
}
return true;
}
//修改数据,将原值修改为新值
public boolean modify(int oldvalue,int newvalue) {
int i=find(oldvalue);
if(i==-1) {
System.out.println("修改的数据不存在");
return false;
}else {
intArray[i]=newvalue;
return true;
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
//创建自定义封装数组结构,大小为4
Demo1 myArray=new Demo1(4);
//添加元素
myArray.add(1);
myArray.add(2);
myArray.add(3);
myArray.add(4);
//显示数组元素
myArray.display();
//得到下标为0的元素
int i=myArray.get(0);
//删除4的元素
myArray.delete(4);
//将元素3修改为6
myArray.modify(3,6);
myArray.display();
}
}
三、分析数组的局限性
通过上面的代码,我们发现数组是能完成一个数据结构所有的功能的,而且实现起来也不难,但是数组有着自身的局限性。
数组的局限性分析:
1、插入快:对于无序数组,即元素没有按照从大到小或某个特定的顺序排列,只是按照插入的顺序排列。无序数组增加一个元素很简单,只需要在数组末尾添加元素即可,但是有序数组却不一定了,它需要在指定的位置插入。
2、查找慢:当然如果根据下标来查找是很快的,但是通常我们都是根据元素值来查找,给定一个元素值,对于无序数组,我们需要从数组第一个元素开始遍历,知道找到该元素。有序数组通过特定的算法查找的速度会比无序数组快,后面会有排序算法的学习。
3、删除慢:根据元素值删除,需要先找到元素的位置,然后将元素后面的值整体向前面移动一个位置,比较耗时。
4、数组大小固定:数组一旦创建,其大小就固定了,不能动态扩展数组的长度,因此数组在创建时需要考虑需要的大小,数组过大会白白浪费内存,数组小了,有不够用。
很显然,相对于无序数组来说,插入快,查找和删除比较慢,而且,数组的动态扩展性差,因此,一般不使用数组来存储数据。
四、总结
本章主要讲解了数组的基本用法,以及使用java语言中的类实现了一个数组的数据结构,同时也应该注意到,当使用数组偏于查找和删除时,使用有序数组好些,数组偏于插入时,使用无序数组好些。
五、文章学习链接