您的位置:首页 > 理论基础 > 数据结构算法

Java数据结构和算法系列2--数组

2015-12-28 00:20 465 查看

1.介绍

Java最常用的数据结构就是数组了,Java中得数组有2种数据类型:基本类型(如int,long)和对象类型。在许多编程语言中数组是基本类型,但在Java中把它们当做对象来对待,因此在创建数组时必须使用new操作符:

int[] intArray = new int[100];


[]操作符对编译器来说是一个标志,它说明正在命名的是数组对象而不是普通变量,当然数组变量还可以这么写,就是将它放在变量名的后面:

int intArray[] = new int[100];


在内存中,数组变量名称,只是它的引用(地址),并不是数组本身。

2.数组结构



3.数组操作

3.1 创建数组

前面已经介绍过

int[] intArray = new int[100];


3.2 初始化

创建数组后,如果不另行指定,那么数组会自动初始化为空(特殊的null对象),如果此时尝试访问一个含有null的数组数据项,程序会出现NullPointer的运行时异常。使用下面语法可以对一个基本类型的数组初始化:

int[] intArray = {0,12,31,9,15,2,99};


上面语句就更简单,创建一个数组对象并且对其初始化。

3.3 例子

下面通过一段代码,演示数组的基本操作,包括创建,初始化,添加,查找,删除。

/**
*
*/
package com.tngtech.array;

/**
* 数组基本操作
*
* @author tngtech
* @date 2015年12月27日
*       <p>
*       博客:http://blog.csdn.net/jacman
*       <p>
*       Github:https://github.com/tangthis
*
*/
public class MyArray {
private long[] arry;
private int length;// 数组长度

public MyArray(int max) {
arry = new long[max];
length = 0;
}

public boolean find(long searchKey) {
for (int i = 0; i < length; i++) {
if (arry[i] == searchKey) {
return true;
}
}
return false;
}

public void insert(long value) {
arry[length] = value;
length++;
}

public boolean delete(long value) {
int j;
for (j = 0; j < length; j++) {
if (arry[j] == value) {
break;
}
}

if (j == length) {
return false; // 没有找到数据项
}

// 删除对应数据项,并且将后面元素从被删除的元素位置重新计算
for (int k = j; k < length; k++) {
arry[k] = arry[k + 1];
}

length--;
return true;
}

public void display() {
for (int i = 0; i < length; i++) {
System.out.print(arry[i] + " ");
}
System.out.println();
}

public static void main(String[] args) {
MyArray myArray = new MyArray(100);
//在数据中插入10个元素
myArray.insert(66);
myArray.insert(99);
myArray.insert(22);
myArray.insert(55);
myArray.insert(77);
myArray.insert(44);
myArray.insert(11);
myArray.insert(0);
myArray.insert(33);
myArray.insert(88);

myArray.display();

long searchKey = 33;
if(myArray.find(searchKey)){
System.out.println("找到了" + searchKey);
}else{
System.out.println("没有找到"+searchKey);
}

//删除2个元素
myArray.delete(0);
myArray.delete(22);
myArray.display();
}
}


4.有序数组

4.1 概念

假设一个数组,其中元素都是按照关键字升序或者降序排列,这种数组称为有序数组。

当向这种数组插入数据项时,需要为插入操作找到正确的位置,刚好在稍小值后面,稍大值前面,然后将数据项大的值向后移,以腾出空间。

为什么要按照顺序排列呢?好处之一就是可以通过二分查找显著提高查找速度。

在有序数组假设数据项不重复,就刚才的逻辑得出结论,它的查找速度提高了,但是插入操作速度降低了。

4.2 线性查找和二分查找

4.2.1 线性查找

正如刚才3.3例子所示,线性查找和未排序的数组查找操作相似,依次向后,寻找匹配。在有序数组中,有些不同,当查到一个比待查数据大的值时就退出查找。

4.3.2 二分查找

假设一个数组从1到100,那么二分查找法,就会从中间数字50来比较待查数字的范围,如果小于50,那么就从1-50范围的中间数字来查找即25,如果小于25,那么就从1-25的中间数字来查找即12(整除);反之,如果查找大于50,那么就从50-100中间数组来找到即75,依次类推,直到查到待查数据就退出。

所以二分查找法,就是将有可能的值划分为2部分,最后范围缩小到一个数字那么大,就是待查找的值了。

下面,我们看下二分查找法的例子:

/**
* 二分查找法
*
* @param value
* @return
*/
public int halfFind(long searchKey){
int lowerBound = 0;
int upperBound = length - 1;

int curBound;
while(true){
curBound = (lowerBound + upperBound) / 2;
if(arry[curBound] == searchKey){
return curBound;
}else if(lowerBound > upperBound){
return length; //用length表示找不到的位置
}else{
if(arry[curBound] < searchKey){
lowerBound = curBound + 1;
}else{
upperBound = curBound - 1;
}
}
}
}


下面我们来测试下二分查找法,代码如下:

//有序数组操作,二分查找法
public static void sortArrayOper(){
MyArray myArray = new MyArray(100);
for(long i = 1 ; i <= 100; i++){
myArray.insert(i);
}
long searchKey = 90;
int index = myArray.halfFind(searchKey);
if(index != myArray.length){
System.out.println("二分查找法,找到了"+searchKey+",位置:"+index);
}else{
System.out.println("二分查找法,没有找到了"+searchKey);
}
}
public static void main(String[] args) {
//myArryOper();

sortArrayOper();
}


程序跑起来,输出结果为:二分查找法,找到了90,位置:89

所以,有序数组可以使用二分查找法,来提高查找的速度。

Github源码:https://github.com/tangthis/java-data
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 数据结构 算法